{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 代码实现"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，我们将动手编写实现基于视觉词袋模型的图像分类算法。我们先导入必要的库，并导入Caltech-101数据集。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-03T19:00:39.189642Z",
     "iopub.status.busy": "2024-12-03T19:00:39.189303Z",
     "iopub.status.idle": "2024-12-03T19:00:49.344519Z",
     "shell.execute_reply": "2024-12-03T19:00:49.342657Z",
     "shell.execute_reply.started": "2024-12-03T19:00:39.189607Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "from PIL import Image\n",
    "import cv2\n",
    "import numpy as np\n",
    "import os\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.kernel_approximation import AdditiveChi2Sampler\n",
    "import random\n",
    "import math\n",
    "from imutils import paths"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-03T19:00:56.750681Z",
     "iopub.status.busy": "2024-12-03T19:00:56.750216Z",
     "iopub.status.idle": "2024-12-03T19:01:32.317113Z",
     "shell.execute_reply": "2024-12-03T19:01:32.315884Z",
     "shell.execute_reply.started": "2024-12-03T19:00:56.750637Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# 图像数据\n",
    "data = []\n",
    "# 图像对应的标签\n",
    "labels = []\n",
    "# 储存标签信息的临时变量\n",
    "labels_tep = []\n",
    "# 数据集的地址\n",
    "# 请读者自行下载数据集，并将数据集放在代码的同级目录下\n",
    "image_paths = list(paths.list_images('./caltech-101'))\n",
    "\n",
    "for image_path in image_paths:\n",
    "    # 获取图像类别\n",
    "    label = image_path.split(os.path.sep)[-2]\n",
    "    # 读取每个类别的图像\n",
    "    image = cv2.imread(image_path)\n",
    "    # 将图像通道从BGR转换为RGB\n",
    "    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n",
    "    # 统一输入图像的尺寸\n",
    "    image = cv2.resize(image, (200,200), interpolation=cv2.INTER_AREA)\n",
    "    data.append(image)\n",
    "    labels_tep.append(label)\n",
    "\n",
    "name2label = {}\n",
    "tep = {}\n",
    "for idx, name in enumerate(labels_tep):\n",
    "    tep[name] = idx\n",
    "for idx, name in enumerate(tep):\n",
    "    name2label[name] = idx\n",
    "for idx, image_path in enumerate(image_paths):\n",
    "    labels.append(name2label[image_path.split(os.path.sep)[-2]])\n",
    "\n",
    "data = np.array(data)\n",
    "labels = np.array(labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们接着对数据集进行训练集验证集和测试集的划分。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-03T19:01:43.294246Z",
     "iopub.status.busy": "2024-12-03T19:01:43.293809Z",
     "iopub.status.idle": "2024-12-03T19:01:43.898497Z",
     "shell.execute_reply": "2024-12-03T19:01:43.897052Z",
     "shell.execute_reply.started": "2024-12-03T19:01:43.294212Z"
    },
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x_train examples: (5486, 200, 200, 3)\n",
      "      x_test examples: (1829, 200, 200, 3)\n",
      "        x_val examples: (1829, 200, 200, 3)\n"
     ]
    }
   ],
   "source": [
    "(x_train, X, y_train, Y) = train_test_split(data, labels, \n",
    "        test_size=0.4, stratify=labels, random_state=42)\n",
    "(x_val, x_test, y_val, y_test) = train_test_split(X, Y, \n",
    "        test_size=0.5, random_state=42)\n",
    "print(f\"x_train examples: {x_train.shape}\\n\\\n",
    "      x_test examples: {x_test.shape}\\n\\\n",
    "        x_val examples: {x_val.shape}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-11-14T04:15:42.707808Z",
     "iopub.status.busy": "2022-11-14T04:15:42.706668Z",
     "iopub.status.idle": "2022-11-14T04:15:42.717775Z",
     "shell.execute_reply": "2022-11-14T04:15:42.716426Z",
     "shell.execute_reply.started": "2022-11-14T04:15:42.707764Z"
    }
   },
   "source": [
    "我们先进行视觉词典的构建。为了得到视觉词典，首先需要对输入图像的表征进行提取，这里使用SIFT对图像进行处理。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-03T19:01:46.199836Z",
     "iopub.status.busy": "2024-12-03T19:01:46.199431Z",
     "iopub.status.idle": "2024-12-03T19:03:15.830468Z",
     "shell.execute_reply": "2024-12-03T19:03:15.829162Z",
     "shell.execute_reply.started": "2024-12-03T19:01:46.199800Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# 构建一个词典，储存每一个类别的sift信息\n",
    "vec_dict = {i:{'kp':[], 'des':{}} for i in range(102)}\n",
    "\n",
    "sift = cv2.SIFT_create()\n",
    "for i in range(x_train.shape[0]):\n",
    "    # 对图像正则化\n",
    "    tep = cv2.normalize(x_train[i], None, 0, 255, \n",
    "                        cv2.NORM_MINMAX).astype('uint8')\n",
    "    # 计算图像的SIFT特征\n",
    "    kp_vector, des_vector = sift.detectAndCompute(tep, None)\n",
    "    # 特征点和描述符信息储存进词典中\n",
    "    vec_dict[y_train[i]]['kp'] += list(kp_vector)\n",
    "    for k in range(len(kp_vector)):\n",
    "        # des使用kp_vector将其一一对应\n",
    "        vec_dict[y_train[i]]['des'][kp_vector[k]] = des_vector[k]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接着，为了保持类别之间的平衡，为每个类别选取相同个数的特征用于之后的聚类。先统计每个类别的SIFT图像特征个数，找到拥有最少特征个数的类别，然后以该类别的特征个数为标准个数，从每个类别的特征中筛选出标准个数的特征进行后续的聚类任务。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-03T19:06:49.636848Z",
     "iopub.status.busy": "2024-12-03T19:06:49.635984Z",
     "iopub.status.idle": "2024-12-03T19:06:50.591340Z",
     "shell.execute_reply": "2024-12-03T19:06:50.590130Z",
     "shell.execute_reply.started": "2024-12-03T19:06:49.636798Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# 设置最少特征点的数目\n",
    "bneck_value = float(\"inf\")\n",
    "\n",
    "# 确定bneck_value的数值\n",
    "for i in range(102):\n",
    "    if len(vec_dict[i]['kp']) < bneck_value:\n",
    "        bneck_value = len(vec_dict[i]['kp'])\n",
    "\n",
    "# 按照每一个SIFT特征点的响应值对特征进行降序排序\n",
    "for i in range(102):\n",
    "    kp_list = vec_dict[i]['kp'] = sorted((vec_dict[i]['kp']), \n",
    "                                         key=lambda x: x.response, \n",
    "                                         reverse=True)\n",
    "    \n",
    "    \n",
    "        \n",
    "# 为每个类别选择同样多的特征点用于聚类。特征点个数bneck_value\n",
    "vec_list=[]\n",
    "for i in range(bneck_value):\n",
    "    vec_list.append(vec_dict[0]['des'][vec_dict[0]['kp'][i]])\n",
    "\n",
    "for i in range(1, 102):\n",
    "    for j in range(bneck_value):\n",
    "        vec_list.append(vec_dict[i]['des'][vec_dict[i]['kp'][j]])\n",
    "\n",
    "vec_list = np.float64(vec_list)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "然后，使用$k$-means聚类算法将这些特征进行聚类，得到的聚类中心组成视觉词典。这里，将聚类中心个数设置为200。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-03T19:07:41.340947Z",
     "iopub.status.busy": "2024-12-03T19:07:41.340507Z",
     "iopub.status.idle": "2024-12-03T19:21:49.036470Z",
     "shell.execute_reply": "2024-12-03T19:21:49.035082Z",
     "shell.execute_reply.started": "2024-12-03T19:07:41.340911Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "from sklearn.cluster import KMeans\n",
    "N_clusters = 200\n",
    "kmeans = KMeans(n_clusters=N_clusters, random_state=0).fit(vec_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们引入空间金字塔匹配算法提升词袋模型的表征能力。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-03T19:22:15.145246Z",
     "iopub.status.busy": "2024-12-03T19:22:15.144834Z",
     "iopub.status.idle": "2024-12-03T19:22:15.158571Z",
     "shell.execute_reply": "2024-12-03T19:22:15.157175Z",
     "shell.execute_reply.started": "2024-12-03T19:22:15.145213Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "def extract_SIFT(img):\n",
    "    sift = cv2.SIFT_create()\n",
    "    descriptors = []\n",
    "    for disft_step_size in DSIFT_STEP_SIZE:\n",
    "        keypoints = [cv2.KeyPoint(x, y, disft_step_size)\n",
    "                for y in range(0, img.shape[0], disft_step_size)\n",
    "                    for x in range(0, img.shape[1], disft_step_size)]\n",
    "\n",
    "        descriptors.append(sift.compute(img, keypoints)[1])\n",
    "    \n",
    "    return np.concatenate(descriptors, axis=0).astype('float64')\n",
    "\n",
    "\n",
    "# 获取图像的SPM特征\n",
    "def getImageFeaturesSPM(L, img, kmeans, k):\n",
    "    W = img.shape[1]\n",
    "    H = img.shape[0]   \n",
    "    h = []\n",
    "    for l in range(L+1):\n",
    "        w_step = math.floor(W/(2**l))\n",
    "        h_step = math.floor(H/(2**l))\n",
    "        x, y = 0, 0\n",
    "        for _ in range(2**l):\n",
    "            x = 0\n",
    "            for __ in range(2**l):\n",
    "                desc = extract_SIFT(img[y:y+h_step, x:x+w_step])                \n",
    "                predict = kmeans.predict(desc)\n",
    "                histo = np.bincount(predict, \n",
    "                        minlength=k).reshape(1,-1).ravel()\n",
    "                weight = 2**(l-L)\n",
    "                h.append(weight*histo)\n",
    "                x = x + w_step\n",
    "            y = y + h_step\n",
    "            \n",
    "    hist = np.array(h).ravel()\n",
    "    hist /= np.sum(hist)\n",
    "    return hist\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "分别使用SPM提取训练集和测试集图像的特征。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-03T19:22:23.283823Z",
     "iopub.status.busy": "2024-12-03T19:22:23.283424Z",
     "iopub.status.idle": "2024-12-03T19:52:27.955380Z",
     "shell.execute_reply": "2024-12-03T19:52:27.953739Z",
     "shell.execute_reply.started": "2024-12-03T19:22:23.283791Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# SPM 的一些超参数\n",
    "pyramid_level = 2\n",
    "DSIFT_STEP_SIZE = [4, 8]\n",
    "\n",
    "hist_vector = []\n",
    "for i in range(x_train.shape[0]):\n",
    "    tep = cv2.normalize(x_train[i], None, 0, 255, cv2.NORM_MINMAX).astype('uint8')\n",
    "    # 提取图像的SPM特征\n",
    "    hist_SPM = getImageFeaturesSPM(pyramid_level, tep, kmeans, N_clusters)\n",
    "    # 将提取的特征加入直方图中\n",
    "    hist_vector.append(hist_SPM)\n",
    "hist_vector = np.array(hist_vector)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-03T19:53:01.893970Z",
     "iopub.status.busy": "2024-12-03T19:53:01.893469Z",
     "iopub.status.idle": "2024-12-03T20:02:59.354768Z",
     "shell.execute_reply": "2024-12-03T20:02:59.353272Z",
     "shell.execute_reply.started": "2024-12-03T19:53:01.893926Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "hist_test_vector = []\n",
    "for i in range(x_test.shape[0]):\n",
    "    tep = cv2.normalize(x_test[i], None, 0, 255, cv2.NORM_MINMAX).astype('uint8')\n",
    "    hist_SPM = getImageFeaturesSPM(pyramid_level, tep, kmeans, N_clusters)\n",
    "    hist_test_vector.append(hist_SPM)\n",
    "hist_test_vector = np.array(hist_test_vector)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后，训练一个SVM分类器，进行图像分类。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-03T20:08:38.781170Z",
     "iopub.status.busy": "2024-12-03T20:08:38.780723Z",
     "iopub.status.idle": "2024-12-03T20:09:56.283098Z",
     "shell.execute_reply": "2024-12-03T20:09:56.281891Z",
     "shell.execute_reply.started": "2024-12-03T20:08:38.781118Z"
    },
    "trusted": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearSVC()"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn import svm\n",
    "\n",
    "# transform使用一种特征映射的方法\n",
    "transformer = AdditiveChi2Sampler()\n",
    "transformer = transformer.fit(np.concatenate(\n",
    "    [hist_vector, hist_test_vector], axis=0)\n",
    "                             )\n",
    "\n",
    "# 构建SVM分类器\n",
    "classifier = svm.LinearSVC()\n",
    "# 将训练的直方图进行特征映射\n",
    "hist_vector = transformer.transform(hist_vector)\n",
    "\n",
    "# 对数据进行拟合\n",
    "classifier.fit(hist_vector, y_train)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后，在测试集上对分类器进行评估，并计算 top-1 错误率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-03T20:10:21.193007Z",
     "iopub.status.busy": "2024-12-03T20:10:21.192558Z",
     "iopub.status.idle": "2024-12-03T20:10:21.845889Z",
     "shell.execute_reply": "2024-12-03T20:10:21.844161Z",
     "shell.execute_reply.started": "2024-12-03T20:10:21.192974Z"
    },
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "top-1 error:  0.3001640240568617\n"
     ]
    }
   ],
   "source": [
    "# 将测试的直方图进行特征映射\n",
    "hist_test_vector = transformer.transform(hist_test_vector)\n",
    "\n",
    "# 计算分类 top-1 错误率\n",
    "top1_error = classifier.predict(hist_test_vector) - y_test\n",
    "tep = len(top1_error[top1_error!=0])\n",
    "print('top-1 error: ', tep/len(y_test))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "为了更深入的了解ResNet，我们先动手编写ResNet34网络。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": [
    "import torch as t\n",
    "from torch import nn\n",
    "from torch.nn import functional as F\n",
    "\n",
    "# 残差结构\n",
    "class ResidualBlock(nn.Module):\n",
    "    \n",
    "    # 深度学习中的图像和利用模型提取的特征图往往有很多通道（channel）\n",
    "    # 比如RGB图像的通道为3，即R通道、B通道与G通道\n",
    "    def __init__(self, inchannel, outchannel, stride=1, shortcut=None):\n",
    "        super(ResidualBlock, self).__init__()\n",
    "        # 观察图 10-6，不难发现残差结构可大致分为左右两部分\n",
    "        # 左边是一系列的网络层级，右边是一个跳跃连接\n",
    "        # 定义左边\n",
    "        self.left = nn.Sequential(\n",
    "            # 对应图 10-6 中第一个权重层\n",
    "            nn.Conv2d(inchannel, outchannel, 3, stride, 1, bias=False),\n",
    "            nn.BatchNorm2d(outchannel),\n",
    "            \n",
    "            # 对应图 10-6 中的 RELU\n",
    "            nn.ReLU(inplace=True),\n",
    "            \n",
    "            # 对应图 10-6 中第二个权重层\n",
    "            nn.Conv2d(outchannel, outchannel, 3, 1, 1, bias=False),\n",
    "            nn.BatchNorm2d(outchannel))\n",
    "        \n",
    "        # 定义右边\n",
    "        self.right = shortcut\n",
    "        \n",
    "    # forward()函数在网络结构中起到举足轻重的作用，它决定着网络如何对数据进行传播\n",
    "    def forward(self, x):\n",
    "        out = self.left(x)\n",
    "        # 构建残差结构\n",
    "        residual = x if self.right is None else self.right(x)\n",
    "        out += residual\n",
    "        \n",
    "        return F.relu(out)\n",
    "\n",
    "\n",
    "# 在这一模块中，将实现 ResNet34，其对应的结构可查看图 10-7\n",
    "class ResNet(nn.Module):\n",
    "    def __init__(self, num_classes=102):\n",
    "        super(ResNet, self).__init__()\n",
    "        # 前几层图像转换\n",
    "        self.pre = nn.Sequential(\n",
    "            nn.Conv2d(3, 64, 7, 2, 3, bias=False),\n",
    "            nn.BatchNorm2d(64),\n",
    "            nn.ReLU(inplace=True),\n",
    "            nn.MaxPool2d(3, 2, 1),\n",
    "        )\n",
    "\n",
    "        # 重复的网络层分别有3、4、6、3个残差块\n",
    "        self.layer1 = self._make_layer(64, 128, 3)\n",
    "        self.layer2 = self._make_layer(128, 256, 4, stride=2)\n",
    "        self.layer3 = self._make_layer(256, 512, 6, stride=2)\n",
    "        self.layer4 = self._make_layer(512, 512, 3, stride=2)\n",
    "\n",
    "        # 分类用的全连接层，将一个多通道的特征图映射到一个维度为类别数目的向量\n",
    "        self.fc = nn.Linear(512, num_classes)\n",
    "\n",
    "    def _make_layer(self, inchannel, outchannel, block_num, stride=1):\n",
    "        # 定义shortcut连接\n",
    "        shortcut = nn.Sequential(\n",
    "            nn.Conv2d(inchannel, outchannel, 1, stride, bias=False),\n",
    "            nn.BatchNorm2d(outchannel))\n",
    "\n",
    "        layers = []\n",
    "        \n",
    "        # 给当前网络层级添加残差块\n",
    "        layers.append(ResidualBlock(inchannel, outchannel, \n",
    "                                    stride, shortcut))\n",
    "\n",
    "        for i in range(1, block_num):\n",
    "            layers.append(ResidualBlock(outchannel, outchannel))\n",
    "\n",
    "        return nn.Sequential(*layers)\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = self.pre(x)\n",
    "\n",
    "        x = self.layer1(x)\n",
    "        x = self.layer2(x)\n",
    "        x = self.layer3(x)\n",
    "        x = self.layer4(x)\n",
    "\n",
    "        x = F.avg_pool2d(x, 7)\n",
    "        x = x.view(x.size(0), -1)\n",
    "\n",
    "        return self.fc(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以使用nn.Covn2d()函数实现卷积操作，该函数定义如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": [
    "nn.Conv2d(in_channels,          # 输入的通道数\n",
    "          out_channels,         # 输出的通道数\n",
    "          kernel_size,          # 卷积核的大小\n",
    "          stride=1,             # 卷积核移动的步长\n",
    "          padding=0,            # 卷积核补零的层数\n",
    "          )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，我们将动手编写完成基于Resnet34的图像分类任务。首先，先导入必要的库。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": [
    "import torch.optim as optim\n",
    "import torch\n",
    "import torch.optim\n",
    "import torch.utils.data as Data\n",
    "import torchvision.transforms as transforms\n",
    "import torchvision.datasets as datasets\n",
    "import torchvision.models\n",
    "from torch.utils.data import DataLoader, Dataset\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们对数据进行增强。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# 定义训练图像增强（变换）的方法\n",
    "train_transform = transforms.Compose(\n",
    "    [transforms.ToPILImage(),\n",
    "     # transforms.Resize((224, 224)),\n",
    "     transforms.ToTensor(),\n",
    "     transforms.Normalize(mean=[0.485, 0.456, 0.406], \n",
    "                          std=[0.229, 0.224, 0.225])])\n",
    "\n",
    "# 定义训练图像增强（变换）的方法\n",
    "val_transform = transforms.Compose(\n",
    "    [transforms.ToPILImage(),\n",
    "     # transforms.Resize((224, 224)),\n",
    "     transforms.ToTensor(),\n",
    "     transforms.Normalize(mean=[0.485, 0.456, 0.406], \n",
    "                          std=[0.229, 0.224, 0.225])])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接着，把Caltech-101数据集封装成类，并生成训练集类、验证集类以及测试集类。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# 数据集\n",
    "class ImageDataset(Dataset):\n",
    "    def __init__(self, images, labels=None, transforms=None):\n",
    "        self.X = images\n",
    "        self.y = labels\n",
    "        self.transforms = transforms\n",
    "\n",
    "    def __len__(self):\n",
    "        return (len(self.X))\n",
    "    \n",
    "    # 用于深度学习训练构建的数据类中，__getitem__()函数非常重要\n",
    "    # __getitem__()决定着数据如何传入模型\n",
    "    # 在下面的代码中，可以发现，当transforms非空时:\n",
    "    # 数据将先经过transforms进行数据增强，再返回进行后续操作\n",
    "    def __getitem__(self, i):\n",
    "        data = self.X[i][:]\n",
    "\n",
    "        if self.transforms:\n",
    "            data = self.transforms(data)\n",
    "\n",
    "        if self.y is not None:\n",
    "            return (data, self.y[i])\n",
    "        else:\n",
    "            return data\n",
    "\n",
    "# 生成不同的类用于训练、验证以及测试\n",
    "train_data = ImageDataset(x_train, y_train, train_transform)\n",
    "val_data = ImageDataset(x_val, y_val, val_transform)\n",
    "test_data = ImageDataset(x_test, y_test, val_transform)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": [
    "BATCH_SIZE = 2048\n",
    "\n",
    "trainloader = DataLoader(train_data, batch_size=BATCH_SIZE, shuffle=True)\n",
    "valloader = DataLoader(val_data, batch_size=BATCH_SIZE, shuffle=True)\n",
    "testloader = DataLoader(test_data, batch_size=BATCH_SIZE, shuffle=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，我们开始加载ResNet34模型。这里将直接调用已经封装好的库。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# 根据当前设备选择使用CPU或者GPU训练\n",
    "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
    "\n",
    "\n",
    "# 加载ImageNet预训练的模型\n",
    "model = torchvision.models.resnet34(pretrained='imagenet')\n",
    "num_ftrs = model.fc.in_features\n",
    "model.fc = nn.Linear(num_ftrs, 102)\n",
    "model.to(device)\n",
    "\n",
    "# 多张GPU并行训练\n",
    "model = nn.DataParallel(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "继续定义训练时需要用到的优化器和损失函数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# 定义优化器\n",
    "optimizer = optim.Adam(model.parameters(), lr=1e-4)\n",
    "# 定义损失函数\n",
    "criterion = nn.CrossEntropyLoss()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，编写训练模型、验证模型以及测试模型top-1错误率的函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# 定义训练函数\n",
    "def fit(model, dataloader):\n",
    "\n",
    "    model.train()\n",
    "    \n",
    "    # 初始化模型损失以及模型 top-1 错误率\n",
    "    running_loss = 0.0\n",
    "    running_top1_error = 0\n",
    "    \n",
    "    # 开始迭代\n",
    "    for i, data in enumerate(dataloader):\n",
    "        \n",
    "        # 准备好训练的图像和标签，每次传入的数据量为batch_size\n",
    "        x, y = data[0].to(device), data[1].to(device)\n",
    "        # 需要在开始进行反向传播之前将梯度设置为零\n",
    "        # 因为PyTorch会在随后的反向传递中累积梯度\n",
    "        optimizer.zero_grad()\n",
    "        \n",
    "        # 将数据传入模型中，获得输出的预测标签\n",
    "        outputs = model(x)\n",
    "        \n",
    "        # 将预测标签与真实标签计算损失\n",
    "        loss = criterion(outputs, y)\n",
    "        \n",
    "        # 记录当前损失\n",
    "        running_loss += loss.item()\n",
    "        \n",
    "        # 记录当前 top-1 错误率\n",
    "        _, preds = torch.max(outputs.data, 1)\n",
    "        running_top1_error += torch.sum(preds != y)\n",
    "        \n",
    "        # 反向传播\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        \n",
    "\n",
    "    loss = running_loss / len(dataloader.dataset)\n",
    "    top1_error = running_top1_error / len(dataloader.dataset)\n",
    "\n",
    "    print(f\"Train Loss: {loss:.4f}, Train Top-1 Error: {top1_error:.4f}\")\n",
    "\n",
    "    return loss, top1_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# 定义验证函数，可以通过验证集对模型的参数进行调整\n",
    "def validate(model, dataloader):\n",
    "\n",
    "    model.eval()\n",
    "    \n",
    "    # 初始化模型损失以及模型 top-1 错误率\n",
    "    running_loss = 0.0\n",
    "    running_top1_error = 0\n",
    "    with torch.no_grad():\n",
    "        for i, data in enumerate(dataloader):\n",
    "            # 流程同训练\n",
    "            x, y = data[0].to(device), data[1].to(device)\n",
    "            outputs = model(x)\n",
    "            loss = criterion(outputs, y)\n",
    "\n",
    "            running_loss += loss.item()\n",
    "            _, preds = torch.max(outputs.data, 1)\n",
    "            running_top1_error += torch.sum(preds != y)\n",
    "            \n",
    "        loss = running_loss / len(dataloader.dataset)\n",
    "        top1_error = running_top1_error / len(dataloader.dataset)\n",
    "        print(f'Val Loss: {loss:.4f}, Val Top-1 Error: {top1_error:.4f}')\n",
    "\n",
    "        return loss, top1_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# 定义测试函数，评估模型的效果\n",
    "def test(model, dataloader):\n",
    "    error = 0\n",
    "    total = 0\n",
    "    with torch.no_grad():\n",
    "        for data in dataloader:\n",
    "            x, y = data[0].to(device), data[1].to(device)\n",
    "            outputs = model(x)\n",
    "            _, predicted = torch.max(outputs.data, 1)\n",
    "            total += y.size(0)\n",
    "            error += torch.sum(predicted != y)\n",
    "    return error, total\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "开始训练模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training on 5486 examples,       validating on 1829 examples...\n",
      "\n",
      "Epoch 1 of 25\n",
      "Train Loss: 0.0024, Train Top-1 Error: 0.8977\n",
      "Val Loss: 0.0019, Val Top-1 Error: 0.6490\n",
      "\n",
      "Epoch 2 of 25\n",
      "Train Loss: 0.0017, Train Top-1 Error: 0.5859\n",
      "Val Loss: 0.0015, Val Top-1 Error: 0.5189\n",
      "\n",
      "Epoch 3 of 25\n",
      "Train Loss: 0.0013, Train Top-1 Error: 0.4424\n",
      "Val Loss: 0.0012, Val Top-1 Error: 0.4117\n",
      "\n",
      "Epoch 4 of 25\n",
      "Train Loss: 0.0011, Train Top-1 Error: 0.3208\n",
      "Val Loss: 0.0010, Val Top-1 Error: 0.3461\n",
      "\n",
      "Epoch 5 of 25\n",
      "Train Loss: 0.0009, Train Top-1 Error: 0.2415\n",
      "Val Loss: 0.0009, Val Top-1 Error: 0.2592\n",
      "\n",
      "Epoch 6 of 25\n",
      "Train Loss: 0.0007, Train Top-1 Error: 0.1743\n",
      "Val Loss: 0.0007, Val Top-1 Error: 0.2056\n",
      "\n",
      "Epoch 7 of 25\n",
      "Train Loss: 0.0005, Train Top-1 Error: 0.1185\n",
      "Val Loss: 0.0006, Val Top-1 Error: 0.1651\n",
      "\n",
      "Epoch 8 of 25\n",
      "Train Loss: 0.0004, Train Top-1 Error: 0.0849\n",
      "Val Loss: 0.0005, Val Top-1 Error: 0.1405\n",
      "\n",
      "Epoch 9 of 25\n",
      "Train Loss: 0.0003, Train Top-1 Error: 0.0631\n",
      "Val Loss: 0.0004, Val Top-1 Error: 0.1241\n",
      "\n",
      "Epoch 10 of 25\n",
      "Train Loss: 0.0003, Train Top-1 Error: 0.0450\n",
      "Val Loss: 0.0004, Val Top-1 Error: 0.1061\n",
      "\n",
      "Epoch 11 of 25\n",
      "Train Loss: 0.0002, Train Top-1 Error: 0.0270\n",
      "Val Loss: 0.0003, Val Top-1 Error: 0.0973\n",
      "\n",
      "Epoch 12 of 25\n",
      "Train Loss: 0.0001, Train Top-1 Error: 0.0149\n",
      "Val Loss: 0.0003, Val Top-1 Error: 0.0869\n",
      "\n",
      "Epoch 13 of 25\n",
      "Train Loss: 0.0001, Train Top-1 Error: 0.0066\n",
      "Val Loss: 0.0003, Val Top-1 Error: 0.0809\n",
      "\n",
      "Epoch 14 of 25\n",
      "Train Loss: 0.0001, Train Top-1 Error: 0.0042\n",
      "Val Loss: 0.0003, Val Top-1 Error: 0.0727\n",
      "\n",
      "Epoch 15 of 25\n",
      "Train Loss: 0.0001, Train Top-1 Error: 0.0018\n",
      "Val Loss: 0.0002, Val Top-1 Error: 0.0705\n",
      "\n",
      "Epoch 16 of 25\n",
      "Train Loss: 0.0000, Train Top-1 Error: 0.0009\n",
      "Val Loss: 0.0002, Val Top-1 Error: 0.0694\n",
      "\n",
      "Epoch 17 of 25\n",
      "Train Loss: 0.0000, Train Top-1 Error: 0.0009\n",
      "Val Loss: 0.0002, Val Top-1 Error: 0.0678\n",
      "\n",
      "Epoch 18 of 25\n",
      "Train Loss: 0.0000, Train Top-1 Error: 0.0004\n",
      "Val Loss: 0.0002, Val Top-1 Error: 0.0683\n",
      "\n",
      "Epoch 19 of 25\n",
      "Train Loss: 0.0000, Train Top-1 Error: 0.0004\n",
      "Val Loss: 0.0002, Val Top-1 Error: 0.0694\n",
      "\n",
      "Epoch 20 of 25\n",
      "Train Loss: 0.0000, Train Top-1 Error: 0.0005\n",
      "Val Loss: 0.0002, Val Top-1 Error: 0.0667\n",
      "\n",
      "Epoch 21 of 25\n",
      "Train Loss: 0.0000, Train Top-1 Error: 0.0002\n",
      "Val Loss: 0.0002, Val Top-1 Error: 0.0672\n",
      "\n",
      "Epoch 22 of 25\n",
      "Train Loss: 0.0000, Train Top-1 Error: 0.0002\n",
      "Val Loss: 0.0002, Val Top-1 Error: 0.0672\n",
      "\n",
      "Epoch 23 of 25\n",
      "Train Loss: 0.0000, Train Top-1 Error: 0.0002\n",
      "Val Loss: 0.0002, Val Top-1 Error: 0.0683\n",
      "\n",
      "Epoch 24 of 25\n",
      "Train Loss: 0.0000, Train Top-1 Error: 0.0004\n",
      "Val Loss: 0.0002, Val Top-1 Error: 0.0683\n",
      "\n",
      "Epoch 25 of 25\n",
      "Train Loss: 0.0000, Train Top-1 Error: 0.0002\n",
      "Val Loss: 0.0002, Val Top-1 Error: 0.0667\n"
     ]
    }
   ],
   "source": [
    "# 开始对模型进行训练\n",
    "\n",
    "# 设定迭代的轮次\n",
    "epochs = 25\n",
    "# 设定训练以及验证的损失与 top-1 错误率\n",
    "train_loss , train_top1_error = [], []\n",
    "val_loss , val_top1_error = [], []\n",
    "\n",
    "print(f\"Training on {len(train_data)} examples, \\\n",
    "      validating on {len(val_data)} examples...\")\n",
    "\n",
    "# 开始迭代\n",
    "for epoch in range(epochs):\n",
    "    # 输出迭代信息\n",
    "    print(f\"\\nEpoch {epoch+1} of {epochs}\")\n",
    "    train_epoch_loss, train_epoch_top1_error = fit(model, trainloader)\n",
    "    val_epoch_loss, val_epoch_top1_error = validate(model, valloader)\n",
    "    train_loss.append(train_epoch_loss)\n",
    "    train_top1_error.append(train_epoch_top1_error.cpu())\n",
    "    val_loss.append(val_epoch_loss)\n",
    "    val_top1_error.append(val_epoch_top1_error.cpu())\n",
    "    \n",
    "# 可以保存训练的模型\n",
    "# torch.save(model.state_dict(), model.pth\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "绘制并观察 top-1 错误率和损失曲线。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "trusted": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7fd1fd5df880>"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1EAAAJaCAYAAADONc3dAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB0cklEQVR4nO3dd3hTdf/G8Tvdi7ZAaVmFsjdlY0VFAWUoCoqg8shwgqgMUUFluMCtKAiK4nr0YcgQFVFEcWARZI8yBcsqZUhLWR05vz/yayDQQgJpT5K+X9eVqydn5ZMYKjffcz5fi2EYhgAAAAAATvEzuwAAAAAA8CaEKAAAAABwASEKAAAAAFxAiAIAAAAAFxCiAAAAAMAFhCgAAAAAcAEhCgAAAABcQIgCAAAAABcEmF1AcbNardq3b59KlSoli8VidjkAAAAATGIYho4dO6aKFSvKz8/58aUSF6L27dun+Ph4s8sAAAAA4CF2796typUrO71/iQtRpUqVkmT7oCIjI02uBgAAAIBZMjMzFR8fb88IzipxISr/Er7IyEhCFAAAAACXb/OhsQQAAAAAuIAQBQAAAAAuIEQBAAAAgAtK3D1RAAAA3s4wDOXm5iovL8/sUgCPFxgYKH9/f7eekxAFAADgRbKzs7V//36dOHHC7FIAr2CxWFS5cmVFRES47ZyEKAAAAC9htVq1c+dO+fv7q2LFigoKCnK5qxhQkhiGoYMHD2rPnj2qVauW20akCFEAAABeIjs7W1arVfHx8QoLCzO7HMArlCtXTrt27VJOTo7bQhSNJQAAALyMnx9/hQOcVRSjtfwJBAAAAAAXEKIAAADgVRISEvTWW2+ZXQZKMEIUAAAAitS1116rIUOGuO18K1as0AMPPHBZ5yjuIPbiiy/qyiuvVFhYmKKjo4vtdVE0CFEAAAAwXf7cV84oV66c1zXWyM7O1u23366BAwcW2Wvk5eXJarUW+NqX4lKPKwkIUQAAACgy/fr10y+//KIJEybIYrHIYrFo165dWrJkiSwWi7777js1b95cwcHB+v3337Vjxw7dcsstiouLU0REhFq2bKkff/zR4ZznjiJZLBZ98MEH6t69u8LCwlSrVi3Nnz+/0JquvfZa/fPPPxo6dKi9pnyzZ89WgwYNFBwcrISEBL3++uvnvfbzzz+vO++8U+Hh4apUqZImTZp00c/h2Wef1dChQ9WoUSMnPznp9OnTGj58uCpVqqTw8HC1bt1aS5YssW//+OOPFR0drfnz56t+/foKDg5WamqqvcY+ffooMjLSPmrn7Hs79zicjxAFAADgpQzD0PHs46Y8DMNwqsYJEyYoKSlJ999/v/bv36/9+/crPj7evn3EiBF66aWXlJKSosaNGysrK0tdunTR4sWLtXr1anXq1Eldu3ZVamrqBV/n2WefVc+ePbVu3Tp16dJFvXv31pEjRwrcd86cOapcubKee+45e02StHLlSvXs2VN33HGH1q9fr7Fjx2rUqFH6+OOPHY5/9dVXlZiYqNWrV2vEiBEaPHiwFi1a5NTn4YqHH35YycnJmj59utatW6fbb79dnTp10rZt2+z7nDhxQi+//LI++OADbdy4UbGxsZKk1157zV7jqFGjnH5v5x6HgjFPFAAAgJc6kXNCEeMjTHntrJFZCg8Kv+h+UVFRCgoKUlhYmMqXL3/e9ueee07XX3+9/XmZMmWUmJhof/78889r7ty5mj9/vh5++OFCX6dfv3668847JUnjxo3T22+/reXLl6tTp07n7VumTBn5+/urVKlSDjW98cYbat++vT081K5dW5s2bdKrr76qfv362fdr06aNRowYYd9n6dKlevPNNx3ex+VKTU3VRx99pNTUVFWsWFGSNHz4cC1cuFAfffSRxo0bJ0nKycnRu+++6/CZSVK7du302GOP2Z/37t3bqfd27nEoGCNRAAAAME2LFi0cnmdlZWn48OGqV6+eoqOjFRERoZSUlIuORDVu3Ni+HB4ersjISKWnp7tUS0pKitq0aeOwrk2bNtq2bZvy8vLs65KSkhz2SUpKUkpKiiRpwIABioiIsD8u1fr165WXl6fatWs7nO+XX37Rjh077PsFBQU5vPd8536uzr63c49DwRiJAgAA8FJhgWHKGpll2mu7Q3i442jW8OHDtWjRIr322muqWbOmQkND1aNHj4s2OQgMDHR4brFYCmyyUNSee+45DR8+/LLPk5WVJX9/f61cuVL+/v4O284OZ6GhoQVOJnvu5+qsSz2upCFEAQAAeCmLxeLUJXVmCwoKchjtuJClS5eqX79+6t69uyRbmNi1a1ex1FSvXj0tXbr0vHpq167tEGSWLVvmsM+yZctUr149SVJsbKz9vqTL0bRpU+Xl5Sk9PV1XX331ZZ/P2fcG53A5HwAAAIpUQkKC/vzzT+3atUuHDh264AhRrVq1NGfOHK1Zs0Zr167VXXfdVSQjSgkJCfr111+1d+9eHTp0SJL02GOPafHixXr++ee1detWffLJJ5o4ceJ5I0tLly7VK6+8oq1bt2rSpEmaNWuWBg8efMHXS01N1Zo1a5Samqq8vDytWbNGa9asUVZWwSOJtWvXVu/evdWnTx/NmTNHO3fu1PLlyzV+/Hh9++23Lr9fZ98bnEOIAgAAQJEaPny4/P39Vb9+fZUrV+6C9ze98cYbKl26tK688kp17dpVHTt2VLNmzdxe03PPPaddu3apRo0aKleunCSpWbNmmjlzpqZPn66GDRtq9OjReu655xwaL0i2QPLXX3+padOmeuGFF/TGG2+oY8eOF3y90aNHq2nTphozZoyysrLUtGlTNW3aVH/99Vehx3z00Ufq06ePHnvsMdWpU0fdunXTihUrVKVKFZffr7PvDc6xGM72p/QRmZmZioqKUkZGhiIjI02t5fU/XteHqz/UQy0f0sOtCu82AwAAIEmnTp3Szp07Va1aNYWEhJhdTomUkJCgIUOGaMiQIWaXAidd6M/NpWYDRqJMlHE6QymHUrQmbY3ZpQAAAABwEiHKRA1jG0qSNqRvMLkSAAAAAM6iO5+JGsU2kiRtPLhRVsMqPwuZFgAAwJMVRadAeB/+1m6immVqKsg/SFnZWUrNuPAEcgAAAAA8AyHKRIH+gaobU1cSl/QBAAAA3oIQZbL8+6LWH1hvciUAAAAAnEGIMlnDcv/fXOIgI1EAAACANyBEmYwOfQAAAIB3IUSZLD9EbT60WTl5OSZXAwAAAOBiCFEmqxpdVRFBEcrOy9b2I9vNLgcAAMAjJSQk6K233rI/t1gsmjdvXqH779q1SxaLRWvWrCny2saOHasmTZoU+evAcxCiTOZn8VODcg0kcUkfAACAs/bv36/OnTu79Zz9+vVTt27dXD5u+PDhWrx4sVtrKcjFgqO7Pfroo2revLmCg4MJiecgRHkA7osCAABwTfny5RUcHGx2GZKkiIgIlS1b1uwyisQ999yjXr16Fdn5s7OzC1yfk3Npt7lc6nGuIkR5AHub83TanAMAAN/y/vvvq2LFirJarQ7rb7nlFt1zzz2SpB07duiWW25RXFycIiIi1LJlS/34448XPO+5ozLLly9X06ZNFRISohYtWmj16tUO++fl5enee+9VtWrVFBoaqjp16mjChAn27WPHjtUnn3yir776ShaLRRaLRUuWLJEkPfnkk6pdu7bCwsJUvXp1jRo1yuEv6+dezme1WvXcc8+pcuXK9lGchQsX2rfnX2o4Z84cXXfddQoLC1NiYqKSk5MLfb8JCQmSpO7du8tisdifS9LkyZNVo0YNBQUFqU6dOvrss8/O+6wmT56szp07KzQ0VNWrV9eXX355wc9Xkt5++20NGjRI1atXv+i++Y4ePar77rtP5cqVU2RkpNq1a6e1a9fat+d/Vh988IGqVaumkJAQhxpvvvlmhYeH68UXX3TpvZ17XFEjRHkARqIAAMClMAzp+HFzHobhXI233367Dh8+rJ9//tm+7siRI1q4cKF69+4tScrKylKXLl20ePFirV69Wp06dVLXrl2Vmprq1GtkZWXppptuUv369bVy5UqNHTtWw4cPd9jHarWqcuXKmjVrljZt2qTRo0frqaee0syZMyXZLsnr2bOnOnXqpP3792v//v268sorJUmlSpXSxx9/rE2bNmnChAmaOnWq3nzzzULrmTBhgl5//XW99tprWrdunTp27Kibb75Z27Ztc9jv6aef1vDhw7VmzRrVrl1bd955p3Jzcws854oVKyRJH330kfbv329/PnfuXA0ePFiPPfaYNmzYoAcffFD9+/d3+LwladSoUbrtttu0du1a9e7dW3fccYdSUlKc+nxdcfvttys9PV3fffedVq5cqWbNmql9+/Y6cuSIfZ/t27dr9uzZmjNnjsM9a2PHjlX37t21fv163XPPPU6/t3OPKxZGCZORkWFIMjIyMswuxW7/sf2GxsqwjLUYJ7JPmF0OAADwUCdPnjQ2bdpknDx50jAMw8jKMgxbnCn+R1aW83Xfcsstxj333GN//t577xkVK1Y08vLyCj2mQYMGxjvvvGN/XrVqVePNN9+0P5dkzJ07136+smXL2j8XwzCMyZMnG5KM1atXF/oagwYNMm677Tb78759+xq33HLLRd/Pq6++ajRv3tz+fMyYMUZiYqL9ecWKFY0XX3zR4ZiWLVsaDz30kGEYhrFz505DkvHBBx/Yt2/cuNGQZKSkpBT6ume/53xXXnmlcf/99zusu/32240uXbo4HDdgwACHfVq3bm0MHDjwwm+0kPdXmN9++82IjIw0Tp065bC+Ro0axnvv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dP/MzExFRUUpIyNDkZGRl10/4G4Dvhmg91a+p6jgKK24f4Vqla110WOys6Unn5Teesv2PClJmj5dqlKlaGsFAADwZpeaDUwdicrOztbKlSvVoUMH+zo/Pz916NBBycnJTp3jxIkTysnJUZkyZQrcfvr0aWVmZjo8AE/2due3XWo0IUlBQdKbb0pz5khRUVJystS0qe2+KQAAALiXqSHq0KFDysvLU1xcnMP6uLg4paWlOXWOJ598UhUrVnQIYmcbP368oqKi7I/4+PjLrhsoSvmNJipEVHC60US+7t2l1aulFi2kI0ekm26yjVBxeR8AAID7mH5P1OV46aWXNH36dM2dO1chISEF7jNy5EhlZGTYH7t37y7mKgHXndtoYvzv450+tlo16fffpUcftT1/5RVb84k9e4qoWAAAgBLG1BAVExMjf39/HThwwGH9gQMHVL58+Qse+9prr+mll17SDz/8oMaNGxe6X3BwsCIjIx0egDdIik+yN5p45qdnnGo0kS84WJowQfrySykyUlq6VGrSRPruuyIqFgAAoAQxNUQFBQWpefPmWrx4sX2d1WrV4sWLlZSUVOhxr7zyip5//nktXLhQLVq0KI5SAVPc3/x+PdDsARkydNfsu7T9yHaXjr/tNmnVKqlZM+nwYalLF+mpp6Tc3CIqGAAAoAQw/XK+YcOGaerUqfrkk0+UkpKigQMH6vjx4+rfv78kqU+fPho5cqR9/5dfflmjRo3StGnTlJCQoLS0NKWlpSkrK8ustwAUqbc7v62kykm2RhPTnWs0cbYaNaQ//pAeftj2fPx4W0t0ZgUAAAC4NKaHqF69eum1117T6NGj1aRJE61Zs0YLFy60N5tITU3V/v377ftPnjxZ2dnZ6tGjhypUqGB/vPbaa2a9BaBIBQcEa3bP2aoQUUEbD25U/6/6O91own6OYOmdd6SZM6VSpaTffrNd3vf990VTMwAAgC8zfZ6o4sY8UfBWf+z+Q9d+fK1yrDka126cRl498uIHFWD7dun226U1aySLxXZ539ixUkCAW8sFAADweF45TxQA510Zf6UmdrFNSv30T0/ru22X1iWiZk3bPFIDB0qGIb34otShg7RvnzurBQAA8F2EKMCLPND8gTONJua43mgiX0iI9O670v/+J0VESL/8Yru8b9Ei99YLAADgiwhRgJfJbzRx9NRRdZve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",
      "text/plain": [
       "<Figure size 1000x700 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA2sAAAJaCAYAAACx5N8sAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB3a0lEQVR4nO3deXxU1d3H8c8kZIFAwp4QZZVFUAREQHCvKC5VUauotKhVqYq0irgLLnW31v0Rl1a0lYpYt6qlKu6KgCwKCCjIphB2EvZs8/xxSSASIAlJZpJ83q/Xfc2Ze8+98xs6rzx+n3PuuaFwOBxGkiRJkhRVYiJdgCRJkiRpV4Y1SZIkSYpChjVJkiRJikKGNUmSJEmKQoY1SZIkSYpChjVJkiRJikKGNUmSJEmKQoY1SZIkSYpCtSJdQHWWn5/PsmXLqFevHqFQKNLlSJIkSYqQcDjMhg0bSE9PJyamZGNmhrUKtGzZMpo3bx7pMiRJkiRFiaVLl7L//vuXqK9hrQLVq1cPCP4HSU5OjnA1kiRJkiIlKyuL5s2bF2aEkjCsVaCCqY/JycmGNUmSJEmluj3KBUYkSZIkKQoZ1iRJkiQpChnWJEmSJCkKec+aJEmSqqVwOExubi55eXmRLkU1QGxsLLVq1SrXR3YZ1iRJklTtZGdns3z5cjZv3hzpUlSD1KlTh2bNmhEfH18u1zOsSZIkqVrJz89n4cKFxMbGkp6eTnx8fLmOdki/FA6Hyc7OZtWqVSxcuJB27dqV+MHXe2JYkyRJUrWSnZ1Nfn4+zZs3p06dOpEuRzVE7dq1iYuLY/HixWRnZ5OYmLjP13SBEUmSJFVL5TGyIZVGef/m/AVLkiRJUhQyrEmSJElSFDKsSZIkSdVUq1ateOSRRyJ+DZWNC4xIkiRJUeLYY4+la9eu5RaOpkyZQlJSUrlcS5XPsCZJkiRVIeFwmLy8PGrV2vt/yjdp0qQSKlJFcRqkJEmSqr9wGHI3RWYLh0tU4kUXXcQnn3zCo48+SigUIhQKsWjRIj7++GNCoRD//e9/6d69OwkJCXz++ecsWLCAM844g9TUVOrWrUuPHj344IMPilzzl1MYQ6EQzz33HGeeeSZ16tShXbt2vPXWW6X6p1yyZAlnnHEGdevWJTk5mXPPPZcVK1YUHv/mm2847rjjqFevHsnJyXTv3p2vv/4agMWLF3PaaafRoEEDkpKSOOigg3j33XdL9fk1iSNrkiRJqv7yNsMrdSPz2eduhFp7n4r46KOP8v3333PwwQdz5513AsHI2KJFiwC48cYb+ctf/kKbNm1o0KABS5cu5ZRTTuHuu+8mISGBF198kdNOO4158+bRokWL3X7OHXfcwQMPPMCDDz7I448/zsCBA1m8eDENGzbca435+fmFQe2TTz4hNzeXIUOGMGDAAD7++GMABg4cSLdu3XjqqaeIjY1lxowZxMXFATBkyBCys7P59NNPSUpK4rvvvqNu3Qj971IFGNYkSZKkKJCSkkJ8fDx16tQhLS1tl+N33nknJ5xwQuH7hg0b0qVLl8L3f/7zn3n99dd56623uOqqq3b7ORdddBHnn38+APfccw+PPfYYkydP5qSTTtprjRMmTGDmzJksXLiQ5s2bA/Diiy9y0EEHMWXKFHr06MGSJUu47rrrOPDAAwFo165d4flLlizh7LPPpnPnzgC0adNmr59ZkxnWJEmSVP3F1glGuCL12eXgsMMOK/J+48aN3H777bzzzjssX76c3NxctmzZwpIlS/Z4nUMOOaSwnZSURHJyMitXrixRDXPmzKF58+aFQQ2gU6dO1K9fnzlz5tCjRw+GDRvGpZdeyj/+8Q/69u3LOeecwwEHHADAH//4R6644gree+89+vbty9lnn12kHhXlPWuSJEmq/kKhYCpiJLZQqFy+wi9XdRw+fDivv/4699xzD5999hkzZsygc+fOZGdn7/E6BVMSd/zThMjPzy+XGgFuv/12Zs+ezamnnsqHH35Ip06deP311wG49NJL+fHHH/nd737HzJkzOeyww3j88cfL7bOrG8OaJEmSFCXi4+PJy8srUd8vvviCiy66iDPPPJPOnTuTlpZWeH9bRenYsSNLly5l6dKlhfu+++471q9fT6dOnQr3tW/fnmuuuYb33nuPs846i+eff77wWPPmzbn88st57bXXuPbaa3n22WcrtOaqzLBWk5RwJSJJkiRFRqtWrZg0aRKLFi1i9erVexzxateuHa+99hozZszgm2++4YILLijXEbLi9O3bl86dOzNw4ECmTZvG5MmTGTRoEMcccwyHHXYYW7Zs4aqrruLjjz9m8eLFfPHFF0yZMoWOHTsCcPXVV/O///2PhQsXMm3aND766KPCY9qVYa0mWP4+jO8BX/420pVIkiRpD4YPH05sbCydOnWiSZMme7z/7K9//SsNGjSgT58+nHbaafTr149DDz20QusLhUK8+eabNGjQgKOPPpq+ffvSpk0bxo4dC0BsbCxr1qxh0KBBtG/fnnPPPZeTTz6ZO+64A4C8vDyGDBlCx44dOemkk2jfvj3/93//V6E1V2WhcNjhloqSlZVFSkoKmZmZJCcnR66QFR/BhF9BUks4Y1Hk6pAkSaoEW7duZeHChbRu3ZrExMRIl6MaZE+/vbJkA0fWaoIG2/8/LJsWw7Y1ka1FkiRJUokY1mqC+BSo2zZor50a2VokSZIklYhhraZo2D14NaxJkiRJVYJhraYwrEmSJElVimGtpjCsSZIkSVWKYa2maFiwyMgiFxmRJEmSqgDDWk0RXx/qHhC0106LaCmSJEmS9s6wVpM4FVKSJEmqMgxrNUlBWFvnyJokSVJ11apVKx555JHC96FQiDfeeGO3/RctWkQoFGLGjBkVXtvtt99O165dK/xz9vadqwrDWk3iyJokSVKNs3z5ck4++eRyveZFF11E//79S33e8OHDmTBhQrnWUp3VinQBqkQFi4xs/BGy10F8g8jWI0mSpAqXlpYW6RIK1a1bl7p160a6jCrDkbWaJL4B1G0TtF1kRJIkKao888wzpKenk5+fX2T/GWecwe9//3sAFixYwBlnnEFqaip169alR48efPDBB3u87i+nBE6ePJlu3bqRmJjIYYcdxvTp04v0z8vL45JLLqF169bUrl2bDh068OijjxYev/3223nhhRd48803CYVChEIhPv74YwBuuOEG2rdvT506dWjTpg0jRowgJyenyLk7T4PMz8/nzjvvZP/99ychIYGuXbsyfvz4wuMFUzRfe+01jjvuOOrUqUOXLl2YOHFiif5NC8ycOZNf/epX1K5dm0aNGjF48GA2btxYePzjjz+mZ8+eJCUlUb9+fY444ggWL14MwDfffMNxxx1HvXr1SE5Opnv37nz99del+vyycmStpmnYPRhZWzsV0o6PdDWSJEmVIxyGzZsj89l16kAotNdu55xzDkOHDuWjjz7i+OOD/05bu3Yt48eP59133wVg48aNnHLKKdx9990kJCTw4osvctpppzFv3jxatGix18/YuHEjv/71rznhhBP45z//ycKFC/nTn/5UpE9+fj77778/48aNo1GjRnz55ZcMHjyYZs2ace655zJ8+HDmzJlDVlYWzz//PAANGzYEoF69eowePZr09HRmzpzJZZddRr169bj++uuLrefRRx/loYce4umnn6Zbt278/e9/5/TTT2f27Nm0a9eusN8tt9zCX/7yF9q1a8ctt9zC+eefz/z586lVa+9xZtOmTfTr14/evXszZcoUVq5cyaWXXspVV13F6NGjyc3NpX///lx22WX861//Ijs7m8mTJxPa/r/ZwIED6datG0899RSxsbHMmDGDuLi4vX5uuQirwmRmZoaBcGZmZqRL2WH2feHwS4TDn50b6UokSZIqxJYtW8LfffddeMuWLTt2btwYDgeRrfK3jRtLXPsZZ5wR/v3vf1/4/umnnw6np6eH8/LydnvOQQcdFH788ccL37ds2TL88MMPF74Hwq+//nrh9Ro1alTk3+app54KA+Hp06fv9jOGDBkSPvvsswvfX3jhheEzzjhjr9/nwQcfDHfv3r3w/W233Rbu0qVL4fv09PTw3XffXeScHj16hK+88spwOBwOL1y4MAyEn3vuucLjs2fPDgPhOXPm7PZzd/7OzzzzTLhBgwbhjTv97/DOO++EY2JiwhkZGeE1a9aEgfDHH39c7LXq1asXHj169F6/azi8m9/edmXJBk6DrGlcZESSJClqDRw4kH//+99s27YNgJdeeonzzjuPmJjgP9s3btzI8OHD6dixI/Xr16du3brMmTOHJUuWlOj6c+bM4ZBDDiExMbFwX+/evXfp9+STT9K9e3eaNGlC3bp1eeaZZ0r0GWPHjuWII44gLS2NunXrcuutt+72vKysLJYtW8YRRxxRZP8RRxzBnDlziuw75JBDCtvNmjUDYOXKlXutB4Lv3KVLF5KSkop8Rn5+PvPmzaNhw4ZcdNFF9OvXj9NOO41HH32U5cuXF/YdNmwYl156KX379uW+++5jwYIFJfrc8mBYq2kaFCwysgCy10e0FEmSpEpTpw5s3BiZrU6dEpd52mmnEQ6Heeedd1i6dCmfffYZAwcOLDw+fPhwXn/9de655x4+++wzZsyYQefOncnOzi63f6qXX36Z4cOHc8kll/Dee+8xY8YMLr744r1+xsSJExk4cCCnnHIKb7/9NtOnT+eWW24pl9p2nnZYMD3xl/f27Yvnn3+eiRMn0qdPH8aOHUv79u356quvgOA+u9mzZ3Pqqafy4Ycf0qlTJ15/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frGfEwqFdtlefvnlffqu1dqJJ0L9+rB8OXz+eenPb9YPklpC9lpY+mq5lydJkiRVNRENa2PHjmXYsGHcdtttTJs2jS5dutCvXz9WrlxZbP8vv/yS888/n0suuYTp06fTv39/+vfvz6xZswr7PPDAAzz22GOMGjWKSZMmkZSURL9+/di6dWthn+zsbM455xyuuOKKPdb3/PPPs3z58sKtf//+5fK9q6X4eDjzzKBdlqmQMbFwwGVB24VGJEmSJELhcGmfZFx+evXqRY8ePXjiiScAyM/Pp3nz5gwdOpQbb7xxl/4DBgxg06ZNvP3224X7Dj/8cLp27cqoUaMIh8Okp6dz7bXXMnz4cAAyMzNJTU1l9OjRnHfeeUWuN3r0aK6++mrWr1+/y2eFQiFef/31fQpoWVlZpKSkkJmZSXJycpmvU2X8739w0knQpAksWwa1apXu/C3L4Y0WEM6Fk7+BBodUTJ2SJElSJStLNojYyFp2djZTp06lb9++O4qJiaFv375MnDix2HMmTpxYpD9Av379CvsvXLiQjIyMIn1SUlLo1avXbq+5J0OGDKFx48b07NmTv//97+wt127bto2srKwiW43yq19Bo0awahV8/HHpz6/dDPbvH7TnP12elUmSJElVTsTC2urVq8nLyyM1NbXI/tTUVDIyMoo9JyMjY4/9C15Lc83dufPOO3nllVd4//33Ofvss7nyyit5/PHH93jOvffeS0pKSuHWvHnzUn1mlRcXB2efHbTLMhUSoN32hUYW/gNyNpZPXZIkSVIVFPEFRqLViBEjOOKII+jWrRs33HAD119/PQ8++OAez7npppvIzMws3JYuXVpJ1UaRglUhX3sNsrNLf37qcVCvHeRugMX/Kt/aJEmSpCokYmGtcePGxMbGsmLFiiL7V6xYQVpaWrHnpKWl7bF/wWtprllSvXr14qeffmLbtm277ZOQkEBycnKRrcY55hhITYW1a+GDD0p/figG2v4haP/wFETulkpJkiQpoiIW1uLj4+nevTsTJkwo3Jefn8+ECRPo3bt3sef07t27SH+A999/v7B/69atSUtLK9InKyuLSZMm7faaJTVjxgwaNGhAQkLCPl2n2ouNhXPOCdplnQrZ+kKISYB102Ht1+VXmyRJklSFlHK5vvI1bNgwLrzwQg477DB69uzJI488wqZNm7j44osBGDRo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C9qXXgapd0JMAiwfDwuei2xtkiRJqlIiHtaefPJJWrVqRWJiIr169WLy5Ml77D9u3DgOPPBAEhMT6dy5M++++26R4+FwmJEjR9KsWTNq165N3759+eGHH4r0ufvuu+nTpw916tShfv36xX7OkiVLOPXUU6lTpw5NmzbluuuuIzc3d5++q2qIu++GI48Mnr928Y3Q4Y5g/7RhsHFRREuTJElS1RHRsDZ27FiGDRvGbbfdxrRp0+jSpQv9+vVj5crilzv/8ssvOf/887nkkkuYPn06/fv3p3///syaNauwzwMPPMBjjz3GqFGjmDRpEklJSfTr14+tW7cW9snOzuacc87hioIV/H4hLy+PU089lezsbL788kteeOEFRo8ezciRI8v3H0DVU1wcvPwyNGkC33wDT/4ATY6C3I3w1cUQzo90hZIkSaoCQuFw5G6k6dWrFz169OCJJ54AID8/n+bNmzN06FBuvPHGXfoPGDCATZs28fbbbxfuO/zww+natSujRo0iHA6Tnp7Otddey/DhwwHIzMwkNTWV0aNHc9555xW53ujRo7n66qtZv359kf3//e9/+fWvf82yZctITU0FYNSoUdxwww2sWrWK+Pj4En2/rKwsUlJSyMzMJDk5ucT/LqomPvgATjwxuFdt1INQ/zbI2wzdH4UOf4x0dZIkSapEZckGERtZy87OZurUqfTt23dHMTEx9O3bl4kTJxZ7zsSJE4v0B+jXr19h/4ULF5KRkVGkT0pKCr169drtNXf3OZ07dy4MagWfk5WVxezZs3d73rZt28jKyiqyqQbr2xduvz1oXzMS6g4L2jNuhKzvI1aWJEmSqoaIhbXVq1eTl5dXJBABpKamkpGRUew5GRkZe+xf8Fqaa5bmc3b+jOLce++9pKSkFG7Nmzcv8Weqmrr11mB0bcsWuHYcJB8HeVtg4oWQnxfp6iRJkhTFIr7ASHVy0003kZmZWbgtXbo00iUp0mJi4J//hP32g3nz4IV6UKserPkK5v4l0tVJkiQpikUsrDVu3JjY2FhWrFhRZP+KFStIS0sr9py0tLQ99i94Lc01S/M5O39GcRISEkhOTi6ySTRpAq+8ArVqwatvwdz+wf5vR8L6WXs8VZIkSTVXxMJafHw83bt3Z8KECYX78vPzmTBhAr179y72nN69exfpD/D+++8X9m/dujVpaWlF+mRlZTFp0qTdXnN3nzNz5swiq1K+//77JCcn06lTpxJfRyrUpw/cf3/QvnssbDgK8rNh4iDIz4lsbZIkSYpKEZ0GOWzYMJ599lleeOEF5syZwxVXXMGmTZu4+OKLARg0aBA33XRTYf8//elPjB8/noceeoi5c+dy++238/XXX3PVVVcBEAqFuPrqq7nrrrt46623mDlzJoMGDSI9PZ3+/fsXXmfJkiXMmDGDJUuWkJeXx4wZM5gxYwYbN24E4MQTT6RTp0787ne/45tvvuF///sft956K0OGDCEhIaHy/oFUvVxzDZx5JmRnw72LILs+rJsOs+6OdGWSJEmKQrUi+eEDBgxg1apVjBw5koyMDLp27cr48eMLF/NYsmQJMTE78mSfPn0YM2YMt956KzfffDPt2rXjjTfe4OCDDy7sc/3117Np0yYGDx7M+vXrOfLIIxk/fjyJiYmFfUaOHMkLL7xQ+L5bt24AfPTRRxx77LHExsby9ttvc8UVV9C7d2+SkpK48MILufPOOyv6n0TVWSgEf/978Oy1H3+El7rDhVNh9l2w/2nQsHukK5QkSVIUiehz1qo7n7OmYk2fDr17w7ZtcPkhcNS3kHIQnPQ1xCbu/XxJkiRVOVXqOWtSjdWtGzz2WNB+djYsqA+Zs+Hb2yJaliRJkqKLYU2KhMsug9/+FvLy4IkQZAJzHoRVX0a6MkmSJEUJw5oUCaEQjBoFnTrBynXwtzTIDwcPy87dFOnqJEmSFAUMa1KkJCXBq68Gr1Mz4K16sHE+zLhp7+dKkiSp2jOsSZHUsSM880zQfnUjfAt8/zhkfBjRsiRJkhR5hjUp0i64AC6/HMJhGJUIa4BJv4ecrEhXJkmSpAgyrEnR4OGH4dBDIXMrPJkAmYth2rWRrkqSJEkRZFiTokFiIowbBykpMG8bvAwseA5+fjfSlUmSJClCDGtStGjTBl54IWj/F5gCTL4Utq2NZFWSJEmKEMOaFE3OOAOGDw/az8TAwuUw9Y+RrUmSJEkRYViTos0998CRR8LmfHgM+P4lWPpapKuSJElSJTOsSdEmLg5efhmaNIHFwIvA5Mth68pIVyZJkqRKZFiTotF++8GYMRAKwUfAB6tgyhXB8v6SJEmqEQxrUrTq2xduuy1oPw9MfA0WjYloSZIkSao8hjUpmt16K5xwAmwDHgU+HwKbl0W6KkmSJFUCw5oUzWJj4Z//hPR0WAY8lQlfXeJ0SEmSpBrAsCZFu6ZNYezYILhNBP45Hhb8LdJVSZIkqYIZ1qSq4Mgj4b77gvY/gFf/CBsXRbIiSZIkVTDDmlRVXHstnH465AJ/3QIf/A7C+ZGuSpIkSRXEsCZVFaEQvPACtNofVgF3fQ7znoh0VZIkSaoghjWpKqlfH159A+JqwVTgrmth/cwIFyVJkqSKYFiTqpru3eHRR4P2v3LhiRNg66rI1iRJkqRyZ1iTqqLLr4ALzoV84P4V8MopkJcd6aokSZJUjgxrUlUUCsFzo+HQzrARuOVr+OQyn78mSZJUjRjWpKqqdm1467+Q2hB+Aq57EeY+GumqJEmSVE4Ma1JVtt9+QWCLrwXTgJuugeXvRboqSZIklQPDmlTV9ewJz/09aL8J3NcfsuZFsiJJkiSVA8OaVB387ncw/Nqg/dQWeO5EyF4X2ZokSZK0TwxrUnVx3/1wUl/IAe5aAm/2h/zcSFclSZKkMjKsSdVFbCyM/Te0bw3rgJs+ha+ujnRVkiRJKiPDmlSdJCfDO+9BSl1YANz4JPzwTKSrkiRJUhkY1qTqpm1b+PcbEBsDnwF3XAErP410VZIkSSolw5pUHR1/PPz14aA9Jh8ePQ02LoxsTZIkSSoVw5pUXQ0dCr+/CMLAw1nwz36QsyHSVUmSJKmEDGtSdRUKwVNPQ5+esAW44wf437kQzo90ZZIkSSoBw5pUncXHw+v/gf3TIAO4aTxMvTnSVUmSJKkEDGtSdde0Kfznv1A7AWYBI+6HhS9FuipJkiTthWFNqgm6doV/bA9o44H7LoLVkyJYkCRJkvbGsCbVFGefDbfdFrT/lgvPnAKbf4psTZIkSdotw5pUk4wcCWeeAXnA/Wvh1VMgd3Okq5IkSVIxDGtSTRITE0yH7NwRsoCRM+GjQRAOR7oySZIk/YJhTappkpKCBUca1YfFwIh/w6y7Il2VJEmSfsGwJtVELVvCG/+BuFiYBNw5Epa+FumqJEmStBPDmlRTHXlk8NBsgFeBR86HdTMiWZEkSZJ2YliTarJLLoGhVwXtJ7PhhZNgy4rI1iRJkiTAsCbprw/Dr46BbcDdK+A/p0HetkhXJUmSVOMZ1qSarlYtGPcatGkJq4HbpsCXg10hUpIkKcIMa5KgYUN4+79Qtw7MBW5/Eeb8NdJVSZIk1WiGNUmBjh1h7DgIheBD4MHrYNl/I12VJElSjWVYk7TDKafAffcF7RfD8PRvIHNOZGuSJEmqoQxrkoq67joYeAHkA3/dDC+fBNvWRLoqSZKkGsewJqmoUAie+xscdihsBP68BP53FuTnRLoySZKkGsWwJmlXiYnw5n+gWVP4Gbj9U5j8p0hXJUmSVKMY1iQVLz0d3nwbEuJgOnDPU/DDU5GuSpIkqcYwrEnavR494O+jg/Z/gEeHwIqPIlmRJElSjWFYk7RnF1wAN9wQtJ8Jw/P9YcP8iJYkSZJUExjWJO3d3XfDqSdDDvBAFow7DjYtjXRVkiRJ1ZphTdLexcbCmJehY3tYB1z/Ezx7BGzJiHRlkiRJ1ZZhTVLJJCfDO+OhXRtYA9y4FP7cE7aujnRlkiRJ1ZJhTVLJtW4Nk76G44+CbcC9S+HSzrDVh2ZLkiSVN8OapNJp0ADGfwhXDArev5QBJ7SH9U6JlCRJKk+GNUmlV6sW/N8L8NjtEAt8vhZ6tIMf50W4MEmSpOrDsCap7IbeBm89B8khmL8Ruh8Cn/kcNkmSpPJgWJO0b065BD56FVrEwPpsOL4vPP+3SFclSZJU5RnWJO27Q8+Cj96GHjGQkw+/vxSuHQZ5eZGuTJIkqcoyrEkqH21OhtfehrO2/1n568Nw2q8hMzOydUmSJFVRhjVJ5Wf/k+HR12FoDMQD/x0Phx8OP/wQ6cokSZKqHMOapPK1/+lw7RgYGYIGwNy50KsXTJgQ6cokSZKqFMOapPLXcgCc/zz8GTgAWLcO+vWDJ56AcDjS1UmSJFUJhjVJFaPNhXDiKLgVOJJgsZGhQ+HyyyE7O9LVSZIkRb1akS5AUjXW7g+QtwXiroHmwMsheOYZmDcPXn0VGjeOdIWSJElRy5E1SRXrwKuh6z3wa+DaMCQlwiefQI8eMHNmpKuTJEmKWoY1SRXvoJvgoFuhGzByK7RoAosWQZ8+8NZbka5OkiQpKhnWJFWOQ+6EA4fB/sDNq6B3J9i4Efr3h3vvdeERSZKkXzCsSaocoRB0+wu0uwLqAVfMhd/1C0LazTfDb38LW7ZEukpJkqSoYViTVHlCITjsCWhzEcTmwykfwr1XQq1aMGYMHHMMLFsW6SolSZKigmFNUuUKxUDP56DleZCfA63+Bi/fBw0bwpQpwcIjU6ZEukpJkqSIM6xJqnwxsdD7Rdi/P+Rvg9yR8N//g4MOCkbWjjoqGGmTJEmqwQxrkiIjJg6OeBmanQR5m2HRZfCfx+DXv4Zt22DgwOBetvz8SFcqSZIUEYY1SZETmwBHvQapx0HuBvj6bHj+drjhhuD4vffCmWfChg0RLVOSJCkSDGuSIqtWbTj6LWjcB3LWwycnwU2D4B//gISE4DlsffrAjz9GulJJkqRKZViTFHlxdeHYd6HhYbBtNUw4Hk7vBZ98As2awaxZ0KULPPww5OZGulpJkqRKYViTFB3iU+C4/0H9Q2BrBnx4PByUGqwM2adP8ADtYcOge3f48stIVytJklThDGuSokdCQ/jV+5B8IGxeGgS2BsBnn8Ezz0CDBvDtt3DEEXDppbB6daQrliRJqjCGNUnRJbEp/OoDqNsGNv4YBLZtq+Cyy2DePPj974N+f/sbdOgAzz3nipGSJKlaMqxJij519oPjP4Q6zSFrHnx0AmxbA02aBCHt88+hc2dYuzYIcUccATNmRLpqSZKkcmVYkxSdkloGga12M1g/M1h0ZNPS4NgRR8DUqfDQQ1C3Lnz1VXAv29VXQ1ZWRMuWJEkqL4Y1SdGrXttgSmRiU1j/DfyvB6yeFByLiwsWHJkzB845J5gK+eijcOCBMHYshMORrV2SJGkfGdYkRbeUTtBv8vZVIlfAB8fAojE7ju+/P7zyCowfD23bwvLlcN55cOKJ8P33katbkiRpHxnWJEW/pJZwwhew/xmQvw2+HAjf3ALhnRYW6dcPZs6EO+4IHqb9wQfBfW0jRsCWLZGrXZIkqYwMa5Kqhri6cNRr0OnG4P3se+Cz30DOxh19EhNh5EiYPRtOOgmys+Guu+Cgg+CddyJTtyRJUhkZ1iRVHaEY6Hov9H4RYuLhp9fh/SNh05Ki/Q44AN59F/7972Ca5MKF8Otfw1lnwZIlxV9bkiQpyhjWJFU9rX8Hx3+808IjPWHVxKJ9QqEgnM2ZA9ddB7VqweuvQ8eO8MADwaibJElSFIuKsPbkk0/SqlUrEhMT6dWrF5MnT95j/3HjxnHggQeSmJhI586deffdd4scD4fDjBw5kmbNmlG7dm369u3LDz/8UKTP2rVrGThwIMnJydSvX59LLrmEjRt3TKdatGgRoVBol+2rr74qvy8uqeya9IZ+U6B+l2DhkQnHwsJ/7Nqvbt0gnE2fDkceCZs3ww03QLdu8MknlV62JElSSUU8rI0dO5Zhw4Zx2223MW3aNLp06UK/fv1YuXJlsf2//PJLzj//fC655BKmT59O//796d+/P7NmzSrs88ADD/DYY48xatQoJk2aRFJSEv369WPr1q2FfQYOHMjs2bN5//33efvtt/n0008ZPHjwLp/3wQcfsHz58sKte/fu5f+PIKlsklrACZ/D/v0hPxsmDoIZNxVdeKTAwQfDp5/C6NHQuDF89x0ceywMGgQrVlRy4ZIkSXsXCocj+zCiXr160aNHD5544gkA8vPzad68OUOHDuXGG2/cpf+AAQPYtGkTb7/9duG+ww8/nK5duzJq1CjC4TDp6elce+21DB8+HIDMzExSU1MZPXo05513HnPmzKFTp05MmTKFww47DIDx48dzyimn8NNPP5Gens6iRYto3bo106dPp2vXrmX6bllZWaSkpJCZmUlycnKZriGpBML58O2IYNERCFaN7P3PYFGS4qxdC7fcAk8/HTyPrX59uOceGDwYYmMrrWxJklRzlCUbRHRkLTs7m6lTp9K3b9/CfTExMfTt25eJEycWe87EiROL9Afo169fYf+FCxeSkZFRpE9KSgq9evUq7DNx4kTq169fGNQA+vbtS0xMDJMmTSpy7dNPP52mTZty5JFH8tZbb+3x+2zbto2srKwim6RKEIqBLncHAS0mAX56E94/AjYtLr5/w4bw1FPw1Vdw6KGwfj1ceSUcfjh8/XWlli5JkrQ7EQ1rq1evJi8vj9TU1CL7U1NTycjIKPacjIyMPfYveN1bn6ZNmxY5XqtWLRo2bFjYp27dujz00EOMGzeOd955hyOPPJL+/fvvMbDde++9pKSkFG7Nmzff2z+BpPLUeiD0/QQSU2H9t9sXHvly9/179oTJk+GJJyA5OQhqPXvCkCGwbl3l1S1JklSMiN+zFq0aN27MsGHDCqdp3nffffz2t7/lwQcf3O05N910E5mZmYXb0qVLK7FiSQA07hUsPNKgK2xdCROOgx9f3H3/2NggnM2bBwMHBtMi/+//4MAD4YUXIC+v0kqXJEnaWUTDWuPGjYmNjWXFL27uX7FiBWlpacWek5aWtsf+Ba976/PLBUxyc3NZu3btbj8Xgvvr5s+fv9vjCQkJJCcnF9kkRUBS82DhkeZnBQuPfHUhTL8B8vcQvNLS4J//hA8/DILaypVw0UXQrh089hjstFqsJElSZYhoWIuPj6d79+5MmDChcF9+fj4TJkygd+/exZ7Tu3fvIv0B3n///cL+rVu3Ji0trUifrKwsJk2aVNind+/erF+/nqlTpxb2+fDDD8nPz6dXr167rXfGjBk0a9as9F9UUuWrlQRHjoODbg3ez3kAPjsTcjbs+bzjjoNvvoH77gvubVu4EP70J2jeHG68EX7+ueJrlyRJIgpWgxw7diwXXnghTz/9ND179uSRRx7hlVdeYe7cuaSmpjJo0CD2228/7r33XiBYuv+YY47hvvvu49RTT+Xll1/mnnvuYdq0aRx88MEA3H///dx333288MILtG7dmhEjRvDtt9/y3XffkZiYCMDJJ5/MihUrGDVqFDk5OVx88cUcdthhjBkzBoAXXniB+Ph4unXrBsBrr73GiBEjeO6557j44otL9N1cDVKKEov+BV9dDPnbIOVgOOY/ULfV3s/bvDmYCvnww1DwrMZateD88+Haa6FLlwotW5IkVR9lygbhKPD444+HW7RoEY6Pjw/37Nkz/NVXXxUeO+aYY8IXXnhhkf6vvPJKuH379uH4+PjwQQcdFH7nnXeKHM/Pzw+PGDEinJqaGk5ISAgff/zx4Xnz5hXps2bNmvD5558frlu3bjg5OTl88cUXhzds2FB4fPTo0eGOHTuG69SpE05OTg737NkzPG7cuFJ9r8zMzDAQzszMLNV5kirAqknh8L/TwuGXCIdfbRIOr/is5Ofm5YXDb7wRDh91VDgc3NUWbMcfHw6/805wXJIkaQ/Kkg0iPrJWnTmyJkWZzT/BJ2fAumkQEwc9n4E2F5XuGlOmwEMPwauv7lh8pGNHGDYMfvtb2D56L0mStLMq95w1SapUdfaHEz6F5r+B/JxgauT06/a88Mgv9egBL78MCxYEAa1ePZgzBy67DFq2hDvvhNWrK+47SJKkGsOwJqlmqZUER46Fg0cG7+f8BT7tDzmlfIh9y5bBCNvSpfCXvwQLkKxcCbfdFrQvvzx4HIAkSVIZGdYk1TyhGDjkDjjiZYhNhGVvw3t9YOOPpb9WSkqw2MiCBTBmDHTvDlu3wtNPB48AOP10+OST4C43SZKkUjCsSaq5Wg6Avp9C7WaQORv+1wtWfla2a8XFBatETpkShLPTT4dQCP7zHzj22GD65JgxkJNTrl9BkiRVX4Y1STVbox7Qbwo07A7bVsOHx8OCv5f9eqEQHH00vPkmzJ0bTIdMTISpU2HgQDjggGDaZGZm+X0HSZJULRnWJKnOfsEIW4tzg4VHJl0C064t3cIjxWnfHp56Kriv7c47oWnToH3ddcF9bcOGweLF5fMdJElStWNYkySAWnWCe9g63x68n/tX+OQ02FoOKzs2bgwjRgTB7LnnoFMn2LAheNj2AQfAeecF0yclSZJ2YliTpAKhEHS+DY58BWJrw/L/wrsHw0//KZ/rJybCJZfArFnw3/9C377Bs9rGjoWePeGoo+CNNyA3t3w+T5IkVWmGNUn6pRbnwAlfQEon2LoCPj09eCZbdjndZxYKwUknwfvvw4wZMGhQsEDJ55/DmWdCs2ZBqHvnnWBlSUmSVCOFwmHXk64oZXlKuaQokrcVvh0Bcx4CwlCnORz+PKQdX/6ftWwZPPEEPPMMrFmzY3/dunDKKXDWWcFrvXrl/9mSJKnClSUbGNYqkGFNqiZWfgZfXbTjOWztr4Ku9wUP2C5vubnw6afw+uvB9vPPO47Fx8MJJwSjb6efDk2alP/nS5KkCmFYizKGNakaydkIM66HH54K3tdtC71fgCZ9Ku4z8/Ph66+D0Pbaa/D99zuOxcQE97ideWawtWhRcXVIkqR9ZliLMoY1qRpa/h589XvY8jOEYqDjddD5DohNqNjPDYdhzpwdwW3atKLHu3cPQttZZ0HHjhVbiyRJKjXDWpQxrEnVVPZ6mPonWPhi8D7lYOj9IjTsVnk1LF4crBz52mvBwiT5+TuOdeiwI7gddliwoIkkSYoow1qUMaxJ1dzSN2DKH2DrSgjVgoNHwkE3QUytyq1j5Up4661g1O2DDyA7e8ex/fffMVXyqKOgViXXJkmSAMNa1DGsSTXA1lUw5XJY+lrwvmGP4F62lAhNRczKgnffDYLbO+/Apk07jjVqFCxMcuaZwUIliYmRqVGSpBrIsBZlDGtSDREOw6Ix8PVVkLMeYhKgyz1w4NXBfW2RsnVrMNL22mvByNsvHwlw8slBcDv1VPBvlCRJFcqwFmUMa1INs/lnmHQpLB8fvG96dPBctrptIlsXBI8E+PzzILi9/jr89NOOY3FxcMwxcNxxwXbYYcE+SZJUbgxrUcawJtVA4TAseBamDYPcTcGz2Lo9BG0HR89CH+HwjkcCvP46zJ1b9HhSEhx5ZBDcjj02WGnSe90kSdonhrUoY1iTarCNP8JXF8PKT4P3zU6CXs9Bnf0iW1dx5s4Npkt+9BF88knR6ZIQTJk86qgdI29duxreJEkqJcNalDGsSTVcOB/mPQozboL8bRBXHw57AlpdED2jbL+Unw+zZgXB7eOPg/C2bl3RPsnJcPTRwajbccdBly4QGxuJaiVJqjIMa1HGsCYJgMw5MHEQrP06eN/8LOgxChKbRLauksjPh2+/DcLbRx/Bp59CZmbRPvXrB+GtYNrkIYdATAQXVpEkKQoZ1qKMYU1Sofxc+O4+mHkHhHMhoQn0fAaa9490ZaWTlwczZgSjbgXhbcOGon0aNCi6YMlBBxneJEk1nmEtyhjWJO1i7fRglC1zVvC+1e/gsMcgvn5Eyyqz3FyYPn3HtMnPPoONG4v2adw4CG8F0yY7dYreaaCSJFUQw1qUMaxJKlbeNph5O8x5ILivrfZ+cPjfodmJka5s3+XkwNSpO0bePv8cNm8u2qdJkyC4HXss9OkDBx/sgiWSpGrPsBZlDGuS9mjVlzDxQtg4P3jf7gro+gDE1Y1sXeUpJwemTNkx8vbFF7BlS9E+SUnQqxf07h1shx8OjRpFpFxJkiqKYS3KGNYk7VXuJphxI3z/RPC+bptg8ZFmJ0S2roqybduO8PbppzBp0q73vAG0bx+MuhUEuE6dXHFSklSlGdaijGFNUollTAiey7Z5afA+/VTo9iCkdIxsXRUtLw+++w4mTgy2L7+E77/ftV+9esGI286jb/XrV3q5kiSVlWEtyhjWJJVKdiZ8OxJ++L9gxchQLLS9HDrfVjWW+S8va9bAV1/tCHCTJsGmTbv269ix6OjbgQe66qQkKWoZ1qKMYU1SmWR9DzOuh5/eDN7HpcDBt0L7oRCbENnaIiE3N3hQ986jbwsW7Nqvfv3g3reCANerV/AAb0mSooBhLcoY1iTtkxUfwbRhsG5G8D6pNXR7AJqf7dL3K1fuGH378svgPrhfLlwSCgXPeNt59K19e//tJEkRYViLMoY1SfssPw8W/QO+uRm2LA/2NTkCuv0VGveMbG3RJCcHvv12R3ibOBEWLdq1X8OG0L07dOu2Y2vXzumTkqQKZ1iLMoY1SeUmdxN892DwbLa87SNILS+ArvdCUovI1hatMjKKhrevvw5Wo/ylpCTo0qVogDvoIEiogVNOJUkVxrAWZQxrksrd5p/hm1tg4QvB+9hEOHAYdLoR4upFtrZol50N33wD06bB9OnB9u23sHXrrn3j4oLHBewc4Lp2DVallCSpDAxrUcawJqnCrJ0K066FlZ8E7xNT4ZA/Q5vfQ4zPIyux3FyYN29HeCvY1q8vvn/btkUDXLdukJpaqSVLkqomw1qUMaxJqlDhMPz8FkwbDhvnB/vqd4ZuD1Xfh2pXhnAYFi/eNcD9/HPx/Zs12zXAtW7tQiaSpCIMa1HGsCapUuRlww9Pwaw7IHtdsC/9FOj2l+r/UO3KtGrVrgHuhx+CcPdLKSnBtMmC8NalC3ToAImJlV62JCk6GNaijGFNUqXathZm3QnfP7nTQ7X/AJ1vr1kP1a5MGzcG973tHOBmzQruj/ulmBg44IDgXriC7aCDghBXp07l1y5JqlSGtShjWJMUEbs8VDsZDroVOvyxZj5Uu7JlZ8OcOUUD3MyZu78PLhQKpk3uHOI6dYKOHaFu3UotXZJUcQxrUcawJimiVny8/aHa04P3Sa2h2/3Q/DfeT1XZwmFYsQJmz4bvvtuxzZ4Na9bs/ryWLYsPcSkplVe7JKlcGNaijGFNUsSF82FhwUO1lwX7GveBQx/2odrRYtWqXUPcd98F4W539t9/1xDXqRM0aFB5dUuSSsWwFmUMa5KiRu4mmPMX+O4ByNsc7POh2tFtzZpdA9x338GyZbs/Jy0tuA+uYATugAOgTRto0QLi4yuvdknSLgxrUcawJinqbP4Zvr0VfnwBCPtQ7apo/friQ9zSpbs/JyYGmjffEd5+uTVs6NRYSapghrUoY1iTFLXWTgvuZyt4qHZ8AzjgMmg/xJG2qiorK1jYpCC8zZ0LP/4YbFu37vnc5OTiQ1ybNsF9c47KSdI+M6xFGcOapKhW8FDt6dfDhu+DfaFY2P9M6PAnaHKEoy3VQTgMGRk7gtsvtz1Nq4Qdo3K7C3ONGvk7kaQSMKxFGcOapCohPw+WvQPzHoUVH+7Y3+DQYLn/lue55H91tmULLFoECxYUH+a2bNnz+fXqFQ1vzZtDenrRLcHfjyQZ1qKMYU1SlbN+Jsx7DBb9E/K2T51LbAptL4d2V0DttMjWp8pV8MiB3Y3K/fxzya7TqNGuAa5g22+/4DU1FWrVqtjvI0kRZFiLMoY1SVXW1tWw4Fn4/knYsv0/yGPioMWAYIpko8MiW5+iw5YtsHjxjvC2YEEQ4JYt27Ft21aya4VCQWDbU6BLT4fGjYOpmZJUxRjWooxhTVKVl58DS18LRttWf7ljf+M+QWhrfhbEOBqi3QiHYd26ouHtl2Fu2TJYvhzy8kp2zVq1oFmzomGuWTNo0mTXrX59g52kqGFYizKGNUnVypopQWhbMjYIcQB19od2Q6DtZZDQKLL1qerKy4PVq3cNcb8MditXBgGwpGJjg5G44oJccVujRsE5klQBDGtRxrAmqVrashx+GAXzR8HWlcG+2NrQ6rfBgiT1D45sfaq+cnKCe+h+GegyMmDVqqJbVlbprx8KBc+cK024c/EUSSVkWIsyhjVJ1VreNlj8crCK5LrpO/anHh9MkdzvVAg5BU0Rsm1bMFr3yxC3u23t2rJ9TlJSEPAaNgzC255eC9oNGvjsOqkGMqxFGcOapBohHIZVnweh7afXIZwf7K97ALQfCgdcDHH+DVSUy82FNWtKHu7WrCn5fXbFqVev+CC3t5DniplSlWVYizKGNUk1zqbFwQqS85+FnPXBvlp1oc3FQXBLbhfR8qRyk58fTLVcuzbY1qwp2eu6daW77+6XkpODhVMaNAi2krQL3icmlstXl1Q2hrUoY1iTVGPlboKF/wxG27LmbN8ZgvRTgimSaX2D+4OkmiYvDzIzSxfw1q6F9ev3/bMTE0sf8Ape69Z1ZU1pHxnWooxhTVKNFw5DxgdBaFv2zo79KZ2CkbYW50JCw8jVJ1UVubnBqNy6dUFwK217X/9zLxQKRvVSUnZs9esXfb+3zcCnGs6wFmUMa5K0k6wf4PvH4cfnIXdjsC8mDtJOCB62vf8ZEJ8S2Rql6ig/HzZsKHvYy84unzpKG/iSk4N7+3Z+TU52BU5VWYa1KGNYk6RiZGcGge3H52H9tzv2x8RD+slBcNvvNIirG7kaJQXCYdi6NZi6ubdt/frdH8vJKb+a4uJ2H+R+uW9vx1yVU5XIsBZlDGuStBeZc2DJK7B47E73thE8ty39VGh5bvBaq07kapS0b0oT+HYOfRs2BFtWVrBt2lT+tSUkFA10deoE9/bVrh287mv7l+/j4rxftwYzrEUZw5oklVA4DJmzgtC2eCxsnL/jWK2kYKStxQBIPwliXdFOqpHy8mDjxqIBrqD9y9e97duyJTLfISam+BCXkLDnrSR9Sts/Ls57CCuZYS3KGNYkqQzCYVg3A5ZsD26bFu04FpcM+50BLQcE97rFOoVJUhnk5u46clcQ4rZsCUYCC7ad35ekXdz7aBUTE4S24rZatcp2bG/HY2OD47vb9na8JH1+eTw2NipGNA1rUcawJkn7KByGNVOC4LbkFdj8045jcfWh+ZnBiFvar4LFSiQp2uTnB4u07CngbdtWdCtu3562kvYvz3sHq5KXXoILLoh0FWXKBrUquCZJksouFILGPYOt24OweiIsfgWWjoMty3csVJLQCJqfHQS3psdATGykK5ekwM5TH+vXj2wtOwfHnJxghDEnp/htT8fKejw3d8eWl1f0/S+3vR0vrs/uwmitqht5HFmrQI6sSVIFyc+DVZ9vH3F7Fbat2nEssSk0/00wVbLJkRDyngxJqjHy83cNc3XqRMUjH5wGGWUMa5JUCfJzYeXH20fc/g3Za3ccq50OLc4JRtwaHx4V9yxIkmomw1qUMaxJUiXLz4GMCcGI29LXISdzx7E6LYLgtt+vg+DmqpKSpEpkWIsyhjVJiqC8bbD8vWBhkp/ehNwNO47FJkLjIyD1OEj9FTQ6zAVKJEkVyrAWZQxrkhQlcrfA8vHBNMmMCbA1o+jxWnWhyVHBqpKpv4L6XVykRJJUrgxrUcawJklRKByGrHmw4sPt20dF73MDiG8QrCqZuj28pXTyfjdJ0j4xrEUZw5okVQHhfFg/MwhuGR/Cyk+KTpmEYIXJpscFI29Nj4N6bQ1vkqRSMaxFGcOaJFVB+bmwdtqOkbdVn0PelqJ96uy/fdRt+z1vSS0iU6skqcowrEUZw5okVQN522DN5B3hbfVXkJ9dtE/dA3YKb8dB7bTI1CpJilqGtShjWJOkaih3M6z+MpgyueJDWPs1hPOK9knptNO0yWMgoVFkapUkRQ3DWpQxrElSDZCTBSs/2zHytu4bYOf/0xqClIOgYXdoeGjwWr8LxNWNVMWSpAgwrEUZw5ok1UDb1gSLlBSMvGXNKaZTCJIPDMJbg+0BrkFXiE+p7GolSZXEsBZlDGuSJLZkBPe8rZ0aLFyybhpsWVZ833rtdoS3hodCg26Q0LBy65UkVQjDWpQxrEmSirUlIwhua6cG4W3tNNi8pPi+Sa13TJ9scGjQTmxSufVKkvaZYS3KGNYkSSW2dRWsm150BG7jj8X3rdN8+8hbwX1wh0LtZpVbrySpVAxrUcawJknaJ9nrYO307aNv20Pchu+L71u72a5TKOvsD6GYyq1ZklQsw1qUMaxJkspdThasm1F0GmXWXAjn79o3tnbwDLh6bYOtbtsd7dr7Q0xspZcvSTVVWbJBrQquSZIklae4ZGh6dLAVyN0UPDKgYPrk2qmQ+R3kbYHMWcH2SzHxULdN0QBXty3UOwCSWkJMXOV9J0lSsQxrkiRVdbWSoEmfYCuQnwOblsCG+bBxfvBa0N74I+RnByNyWXN3vV4oFpJabQ9x7YoGuqRWEJtQWd9Mkmo0p0FWIKdBSpKiUn4ebPmpaIDbuZ23dffnhmKgTotdp1XWbRuM1NWqXXnfQ5KqEKdBSpKkvYuJDaY6JrWEtOOLHgvnw5blxYe4DfMhdyNsWhRsfLDrtRMaQ2IqJKZB7bTgNTF113ZCYxc/kaS9MKxJkqQdQjFQZ79gSz2m6LFwGLauLD7EbfgBcjJh2+pgy5y9l8+JhcSmxQe7nd/XToW4+hAKVdhXlqRoZViTJEklEwoF4al2KjQ5ouixcBiy1wajclszggd/b82ArSt2tLdsf79tNYTzgr5blu/9c2PidwpwxYW7phDfEBIaQXwD76mTVG0Y1iRJ0r4LhYKwlNAIOHjPffNzgoeAb12x+2BX0M5ZHyyGsnlJsJVEraQgvMU3hISGO7UbFbNvp2Oxifv6ryBJ5cqwJkmSKldMHNRJD7a9ydu6PbhtD3ZbM37RzoBtq4JRvex1wT13uZuCbfPS0tUVW3vPYa7IvgbBYxRq1YO4ehCT4FRNSeXOsCZJkqJXbOKOxVD2JpwfPDQ8ey1sWwvb1mwPcdvfF7aL2R/OC55Lt+XnYCutUK0gtO0c4Apei7SLOb7zsbh6UKuui69IAgxrkiSpugjFQHz9YKvbpuTnhcM7Ql5xwW7n9zsfz8kKAh5AODcY2cteVz7fpVZS8aGuVlLweITYYrbS7o+JczRQinKGNUmSVLOFQhCfEmy0Lt25+bnB4wxyNkDuhqKvORuCQPfL/Tsfz/1Fv3BecN2CqZxbM8r96xYKxWwPbnX2HOpiE4NFW2K2b7E7vcYm7rqvuH57ejUwSrtlWJMkSSqrmFo7RvP2VTgc3KO321CXBbmbg9G8X265xezb3f7Cz9vp/r5IionbHt5+Efxi4rdvcbtp/+J9bDyE4opvx5TgWOH+WsG01sLXuKLvC9tOVVXFi4qw9uSTT/Lggw+SkZFBly5dePzxx+nZs+du+48bN44RI0awaNEi2rVrx/33388pp5xSeDwcDnPbbbfx7LPPsn79eo444gieeuop2rVrV9hn7dq1DB06lP/85z/ExMRw9tln8+ijj1K3bt3CPt9++y1DhgxhypQpNGnShKFDh3L99ddXzD+CJEmq2UKhYHSrVu3gcQQVIRyG/G27D3K7C31527aft5fXvfbZGqwGurP8nGDL3Vgx37nChLaHtmIC3p7CXnF9QrHb27E73hfZF1tMv33sS8z29zu/bm9TzL5QTPHnEAMxuzmHX5wfig3+3Qr6FB53dHV3Ih7Wxo4dy7Bhwxg1ahS9evXikUceoV+/fsybN4+mTXf9Q/Xll19y/vnnc++99/LrX/+aMWPG0L9/f6ZNm8bBBwdLBT/wwAM89thjvPDCC7Ru3ZoRI0bQr18/vvvuOxITg2V5Bw4cyPLly3n//ffJycnh4osvZvDgwYwZMwaArKwsTjzxRPr27cuoUaOYOXMmv//976lfvz6DBw+uvH8gSZKk8hIKbZ/WmBisaBkJ4fzgcQx7DX45Qb/CLWc37dIc21vf3OD+w/xcCOfseF/8F9kePHMgrzL/AaupIuFtD+1QDIWBb499dmp3vR/ST47glyu7UDgcDkeygF69etGjRw+eeOIJAPLz82nevDlDhw7lxhtv3KX/gAED2LRpE2+//XbhvsMPP5yuXbsyatQowuEw6enpXHvttQwfPhyAzMxMUlNTGT16NOeddx5z5syhU6dOTJkyhcMOOwyA8ePHc8opp/DTTz+Rnp7OU089xS233EJGRgbx8fEA3HjjjbzxxhvMnTu3RN8tKyuLlJQUMjMzSU5O3qd/J0mSJEVAOBwEzPDOQS43CGpF3ucW7VNwvER98rbvy9vRDm9v5+/ULthf3L4i+/dyfjh3+3fK3/5++yvF7NvbMXbXP6IRo6gjXoaWAyJdRZmyQURH1rKzs5k6dSo33XRT4b6YmBj69u3LxIkTiz1n4sSJDBs2rMi+fv368cYbbwCwcOFCMjIy6Nu3b+HxlJQUevXqxcSJEznvvPOYOHEi9evXLwxqAH379iUmJoZJkyZx5plnMnHiRI4++ujCoFbwOffffz/r1q2jQYMI/X+jJEmSVHlCoe3T92KBhEhXU3WEw0B4N+Euf/ux/B0bu2nv7lhJzycfUg6O0D/CvotoWFu9ejV5eXmkpqYW2Z+amrrb0auMjIxi+2dkZBQeL9i3pz6/nGJZq1YtGjZsWKRP69atd7lGwbHiwtq2bdvYtm1b4fusrKxiv4MkSZJUrYVC7JiuqLLyX68c3XvvvaSkpBRuzZs3j3RJkiRJkqqoiIa1xo0bExsby4oVK4rsX7FiBWlpacWek5aWtsf+Ba9767Ny5coix3Nzc1m7dm2RPsVdY+fP+KWbbrqJzMzMwm3p0qXFf3FJkiRJ2ouIhrX4+Hi6d+/OhAkTCvfl5+czYcIEevfuXew5vXv3LtIf4P333y/s37p1a9LS0or0ycrKYtKkSYV9evfuzfr165k6dWphnw8//JD8/Hx69epV2OfTTz8lJyenyOd06NBht/erJSQkkJycXGSTJEmSpLKI+DTIYcOG8eyzz/LCCy8wZ84crrjiCjZt2sTFF18MwKBBg4osQPKnP/2J8ePH89BDDzF37lxuv/12vv76a6666ioAQqEQV199NXfddRdvvfUWM2fOZNCgQaSnp9O/f38AOnbsyEknncRll13G5MmT+eKLL7jqqqs477zzSE9PB+CCCy4gPj6eSy65hNmzZzN27FgeffTRXRY3kSRJkqSKEPHnrA0YMIBVq1YxcuRIMjIy6Nq1K+PHjy9czGPJkiXExOzIlH369GHMmDHceuut3HzzzbRr14433nij8BlrANdffz2bNm1i8ODBrF+/niOPPJLx48cXPmMN4KWXXuKqq67i+OOPL3wo9mOPPVZ4PCUlhffee48hQ4bQvXt3GjduzMiRI33GmiRJkqRKEfHnrFVnPmdNkiRJEpQtG0R8GqQkSZIkaVeGNUmSJEmKQoY1SZIkSYpChjVJkiRJikKGNUmSJEmKQoY1SZIkSYpChjVJkiRJikKGNUmSJEmKQoY1SZIkSYpChjVJkiRJikKGNUmSJEmKQoY1SZIkSYpChjVJkiRJikKGNUmSJEmKQoY1SZIkSYpCtSJdQHUWDocByMrKinAlkiRJkiKpIBMUZISSMKxVoA0bNgDQvHnzCFciSZIkKRps2LCBlJSUEvUNhUsT7VQq+fn5LFu2jHr16hEKhSJaS1ZWFs2bN2fp0qUkJydHtBZVbf6WVB78Ham8+FtSefG3pPKyu99SOBxmw4YNpKenExNTsrvRHFmrQDExMey///6RLqOI5ORk/wCpXPhbUnnwd6Ty4m9J5cXfkspLcb+lko6oFXCBEUmSJEmKQoY1SZIkSYpChrUaIiEhgdtuu42EhIRIl6Iqzt+SyoO/I5UXf0sqL/6WVF7K87fkAiOSJEmSFIUcWZMkSZKkKGRYkyRJkqQoZFiTJEmSpChkWJMkSZKkKGRYqwGefPJJWrVqRWJiIr169WLy5MmRLklVzO23304oFCqyHXjggZEuS1XAp59+ymmnnUZ6ejqhUIg33nijyPFwOMzIkSNp1qwZtWvXpm/fvvzwww+RKVZRbW+/pYsuumiXv1MnnXRSZIpV1Lr33nvp0aMH9erVo2nTpvTv35958+YV6bN161aGDBlCo0aNqFu3LmeffTYrVqyIUMWKViX5LR177LG7/F26/PLLS/U5hrVqbuzYsQwbNozbbruNadOm0aVLF/r168fKlSsjXZqqmIMOOojly5cXbp9//nmkS1IVsGnTJrp06cKTTz5Z7PEHHniAxx57jFGjRjFp0iSSkpLo168fW7dureRKFe329lsCOOmkk4r8nfrXv/5ViRWqKvjkk08YMmQIX331Fe+//z45OTmceOKJbNq0qbDPNddcw3/+8x/GjRvHJ598wrJlyzjrrLMiWLWiUUl+SwCXXXZZkb9LDzzwQKk+x6X7q7levXrRo0cPnnjiCQDy8/Np3rw5Q4cO5cYbb4xwdaoqbr/9dt544w1mzJgR6VJUhYVCIV5//XX69+8PBKNq6enpXHvttQwfPhyAzMxMUlNTGT16NOedd14Eq1U0++VvCYKRtfXr1+8y4ibtyapVq2jatCmffPIJRx99NJmZmTRp0oQxY8bwm9/8BoC5c+fSsWNHJk6cyOGHHx7hihWtfvlbgmBkrWvXrjzyyCNlvq4ja9VYdnY2U6dOpW/fvoX7YmJi6Nu3LxMnToxgZaqKfvjhB9LT02nTpg0DBw5kyZIlkS5JVdzChQvJyMgo8jcqJSWFXr16+TdKZfLxxx/TtGlTOnTowBVXXMGaNWsiXZKiXGZmJgANGzYEYOrUqeTk5BT5u3TggQfSokUL/y5pj375Wyrw0ksv0bhxYw4++GBuuukmNm/eXKrr1iq3ChV1Vq9eTV5eHqmpqUX2p6amMnfu3AhVpaqoV69ejB49mg4dOrB8+XLuuOMOjjrqKGbNmkW9evUiXZ6qqIyMDIBi/0YVHJNK6qSTTuKss86idevWLFiwgJtvvpmTTz6ZiRMnEhsbG+nyFIXy8/O5+uqrOeKIIzj44IOB4O9SfHw89evXL9LXv0vak+J+SwAXXHABLVu2JD09nW+//ZYbbriBefPm8dprr5X42oY1SXt18sknF7YPOeQQevXqRcuWLXnllVe45JJLIliZJAV2njbbuXNnDjnkEA444AA+/vhjjj/++AhWpmg1ZMgQZs2a5T3Y2me7+y0NHjy4sN25c2eaNWvG8ccfz4IFCzjggANKdG2nQVZjjRs3JjY2dpcVjFasWEFaWlqEqlJ1UL9+fdq3b8/8+fMjXYqqsIK/Q/6NUkVo06YNjRs39u+UinXVVVfx9ttv89FHH7H//vsX7k9LSyM7O5v169cX6e/fJe3O7n5LxenVqxdAqf4uGdaqsfj4eLp3786ECRMK9+Xn5zNhwgR69+4dwcpU1W3cuJEFCxbQrFmzSJeiKqx169akpaUV+RuVlZXFpEmT/BulffbTTz+xZs0a/06piHA4zFVXXcXrr7/Ohx9+SOvWrYsc7969O3FxcUX+Ls2bN48lS5b4d0lF7O23VJyChdpK83fJaZDV3LBhw7jwwgs57LDD6NmzJ4888gibNm3i4osvjnRpqkKGDx/OaaedRsuWLVm2bBm33XYbsbGxnH/++ZEuTVFu48aNRf4/iAsXLmTGjBk0bNiQFi1acPXVV3PXXXfRrl07WrduzYgRI0hPTy+yyp8Ee/4tNWzYkDvuuIOzzz6btLQ0FixYwPXXX0/btm3p169fBKtWtBkyZAhjxozhzTffpF69eoX3oaWkpFC7dm1SUlK45JJLGDZsGA0bNiQ5OZmhQ4fSu3dvV4JUEXv7LS1YsIAxY8Zwyimn0KhRI7799luuueYajj76aA455JCSf1BY1d7jjz8ebtGiRTg+Pj7cs2fP8FdffRXpklTFDBgwINysWbNwfHx8eL/99gsPGDAgPH/+/EiXpSrgo48+CgO7bBdeeGE4HA6H8/PzwyNGjAinpqaGExISwscff3x43rx5kS1aUWlPv6XNmzeHTzzxxHCTJk3CcXFx4ZYtW4Yvu+yycEZGRqTLVpQp7jcEhJ9//vnCPlu2bAlfeeWV4QYNGoTr1KkTPvPMM8PLly+PXNGKSnv7LS1ZsiR89NFHhxs2bBhOSEgIt23bNnzdddeFMzMzS/U5PmdNkiRJkqKQ96xJkiRJUhQyrEmSJElSFDKsSZIkSVIUMqxJkiRJUhQyrEmSJElSFDKsSZIkSVIUMqxJkiRJUhQyrEmSFIVCoRBvvPFGpMuQJEWQYU2SpF+46KKLCIVCu2wnnXRSpEuTJNUgtSJdgCRJ0eikk07i+eefL7IvISEhQtVIkmoiR9YkSSpGQkICaWlpRbYGDRoAwRTFp556ipNPPpnatWvTpk0bXn311SLnz5w5k1/96lfUrl2bRo0aMXjwYDZu3Fikz9///ncOOuggEhISaNasGVdddVWR46tXr+bMM8+kTp06tGvXjrfeeqtiv7QkKaoY1iRJKoMRI0Zw9tln88033zBw4EDOO+885syZA8CmTZvo168fDRo0YMqUKYwbN44PPvigSBh76qmnGDJkCIMHD2bmzJm89dZbtG3btshn3HHHHZx77rl8++23nHLKKQwcOJC1a9dW6veUJEVOKBwOhyNdhCRJ0eSiiy7in//8J4mJiUX233zzzdx8882EQiEuv/xynnrqqcJjhx9+OIceeij/93//x7PPPssNN9zA0qVLSUpKAuDdd9/ltNNOY9myZaSmprLffvtx8cUXc9dddxVbQygU4tZbb+XPf/4zEATAunXr8t///td75ySphvCeNUmSinHccccVCWMADRs2LGz37t27yLHevXszY8YMAObMmUOXLl0KgxrAEUccQX5+PvPmzSMUCrFs2TKOP/74PdZwyCGHFLaTkpJITk5m5cqVZf1KkqQqxrAmSVIxkpKSdpmWWF5q165don5xcXFF3odCIfLz8yuiJElSFPKeNUmSyuCrr77a5X3Hjh0B6NixI9988w2bNm0qPP7FF18QExNDhw4dqFevHq1atWLChAmVWrMkqWpxZE2SpGJs27aNjIyMIvtq1apF48aNARg3bhyHHXYYRx55JC+99BKTJ0/mb3/7GwADBw7ktttu48ILL+T2229n1apVDB06lN/97nekpqYCcPvtt3P55ZfTtGlTTj75ZDZs2MAXX3zB0KFDK/eLSpKilmFNkqRijB8/nmbNmhXZ16FDB+bOnQsEKzW+/PLLXHnllTRr1ox//etfdOrUCYA6derwv//9jz/96U/06NGDOnXqcPbZZ/PXv/618FoXXnghW7du5eGHH2b48OE0btyY3/zmN5X3BSVJUc/VICVJKqVQKMTrr79O//79I12KJKka8541SZIkSYpChjVJkiRJikLesyZJUil5B4EkqTI4siZJkiRJUciwJkmSJElRyLAmSZIkSVHIsCZJkiRJUciwJkmSJElRyLAmSZIkSVHIsCZJkiRJUciwJkmSJElRyLAmSZIkSVHo/wHvM2N8CXkgiwAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 1000x700 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制 top-1 错误率曲线\n",
    "plt.figure(figsize=(10, 7))\n",
    "# 训练集的top-1 错误率曲线\n",
    "plt.plot(train_top1_error, color='green', label='train top-1 error')\n",
    "# 验证集top-1 错误率曲线\n",
    "plt.plot(val_top1_error, color='blue', label='validataion top-1 error')\n",
    "plt.xlabel('迭代次数')\n",
    "plt.ylabel('top-1 错误率')\n",
    "plt.legend()\n",
    "\n",
    "# 绘制损失函数曲线\n",
    "plt.figure(figsize=(10, 7))\n",
    "plt.plot(train_loss, color='orange', label='train loss')\n",
    "plt.plot(val_loss, color='red', label='validataion loss')\n",
    "plt.xlabel('迭代次数')\n",
    "plt.ylabel('损失函数')\n",
    "plt.legend()\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后，对模型的 top-1 错误率进行评估。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Top-1 error of the network on test images: 5.358 %\n"
     ]
    }
   ],
   "source": [
    "error, total = test(model, testloader)\n",
    "print('Top-1 error of the network on test images: %0.3f %%' \\\n",
    "      % (100 * (error / total)))"
   ]
  }
 ],
 "metadata": {
  "kaggle": {
   "accelerator": "none",
   "dataSources": [
    {
     "datasetId": 2334639,
     "sourceId": 3932654,
     "sourceType": "datasetVersion"
    },
    {
     "datasetId": 2632619,
     "sourceId": 4503325,
     "sourceType": "datasetVersion"
    }
   ],
   "dockerImageVersionId": 30301,
   "isGpuEnabled": false,
   "isInternetEnabled": true,
   "language": "python",
   "sourceType": "notebook"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.12"
  },
  "vscode": {
   "interpreter": {
    "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
